6 * $Date: 2012-07-18 09:09:28 +0200 (Mi, 18. Jul 2012) $
7 ***************************************************************/
10 * \brief Implementation of System class.
12 * \author Carsten Gutwenger
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
44 #include <ogdf/basic/basic.h>
48 #include <malloc/malloc.h>
49 #include <sys/types.h>
50 #include <sys/sysctl.h>
51 #include <sys/utsname.h>
52 #include <mach/vm_statistics.h>
53 #include <mach/mach.h>
54 #include <mach/machine.h>
55 #elif defined(OGDF_SYSTEM_UNIX)
59 #if defined(OGDF_SYSTEM_WINDOWS) || defined(__CYGWIN__)
66 #elif defined(OGDF_SYSTEM_UNIX) || (defined(__MINGW32__) && !defined(__MINGW64__))
71 static void __cpuid(int CPUInfo
[4], int infoType
)
73 uint32_t a
= CPUInfo
[0];
74 uint32_t b
= CPUInfo
[1];
75 uint32_t c
= CPUInfo
[2];
76 uint32_t d
= CPUInfo
[3];
78 #if defined(__i386__) || defined(__x86_64__) && !defined(__APPLE__)
79 __asm__
__volatile__ ("xchgl %%ebx,%0\n\t"
82 : "+r" (b
), "=a" (a
), "=c" (c
), "=d" (d
)
83 : "1" (infoType
), "2" (c
));
85 // not supported on other systems!
99 unsigned int System::s_cpuFeatures
;
100 int System::s_cacheSize
;
101 int System::s_cacheLine
;
102 int System::s_pageSize
;
103 int System::s_numberOfProcessors
;
106 #if defined(OGDF_SYSTEM_WINDOWS) || defined(__CYGWIN__)
107 LARGE_INTEGER
System::s_HPCounterFrequency
;
117 // currently not working for shared libs on Linux
118 #if !defined(OGDF_DLL) || !defined(OGDF_SYSTEM_UNIX)
120 int CPUInfo
[4] = {-1};
123 unsigned int nIds
= CPUInfo
[0];
128 int featureInfoECX
= CPUInfo
[2];
129 int featureInfoEDX
= CPUInfo
[3];
131 if(featureInfoEDX
& (1 << 23)) s_cpuFeatures
|= cpufmMMX
;
132 if(featureInfoEDX
& (1 << 25)) s_cpuFeatures
|= cpufmSSE
;
133 if(featureInfoEDX
& (1 << 26)) s_cpuFeatures
|= cpufmSSE2
;
134 if(featureInfoECX
& (1 << 0)) s_cpuFeatures
|= cpufmSSE3
;
135 if(featureInfoECX
& (1 << 9)) s_cpuFeatures
|= cpufmSSSE3
;
136 if(featureInfoECX
& (1 << 19)) s_cpuFeatures
|= cpufmSSE4_1
;
137 if(featureInfoECX
& (1 << 20)) s_cpuFeatures
|= cpufmSSE4_2
;
138 if(featureInfoECX
& (1 << 5)) s_cpuFeatures
|= cpufmVMX
;
139 if(featureInfoECX
& (1 << 6)) s_cpuFeatures
|= cpufmSMX
;
140 if(featureInfoECX
& (1 << 7)) s_cpuFeatures
|= cpufmEST
;
141 if(featureInfoECX
& (1 << 3)) s_cpuFeatures
|= cpufmMONITOR
;
144 __cpuid(CPUInfo
, 0x80000000);
145 unsigned int nExIds
= CPUInfo
[0];
147 if(nExIds
>= 0x80000006) {
148 __cpuid(CPUInfo
, 0x80000006);
149 s_cacheLine
= CPUInfo
[2] & 0xff;
150 s_cacheSize
= (CPUInfo
[2] >> 16) & 0xffff;
153 #if defined(OGDF_SYSTEM_WINDOWS) || defined(__CYGWIN__)
154 QueryPerformanceFrequency(&s_HPCounterFrequency
);
156 SYSTEM_INFO siSysInfo
;
157 GetSystemInfo(&siSysInfo
);
158 s_pageSize
= siSysInfo
.dwPageSize
;
159 s_numberOfProcessors
= siSysInfo
.dwNumberOfProcessors
;
161 #elif defined(OGDF_SYSTEM_UNIX) && defined(__APPLE__)
162 unsigned long long value
;
163 size_t size
= sizeof( value
);
164 if (sysctlbyname("hw.pagesize", &value
, &size
, NULL
, 0) !=-1)
165 s_pageSize
= (int)value
;
169 if (sysctlbyname("hw.ncpu", &value
, &size
, NULL
, 0) !=-1)
170 s_numberOfProcessors
= (int)value
;
172 s_numberOfProcessors
= 1;
174 #elif defined(OGDF_SYSTEM_UNIX)
175 s_pageSize
= sysconf(_SC_PAGESIZE
);
176 s_numberOfProcessors
= (int)sysconf(_SC_NPROCESSORS_CONF
);
179 s_pageSize
= 0; // just a placeholder!!!
180 s_numberOfProcessors
= 1; // just a placeholder!!!
187 #if defined(OGDF_SYSTEM_WINDOWS) || defined(__CYGWIN__)
188 void System::getHPCounter(LARGE_INTEGER
&counter
)
190 QueryPerformanceCounter(&counter
);
194 double System::elapsedSeconds(
195 const LARGE_INTEGER
&startCounter
,
196 const LARGE_INTEGER
&endCounter
)
198 return double(endCounter
.QuadPart
- startCounter
.QuadPart
)
199 / s_HPCounterFrequency
.QuadPart
;
203 __int64
System::usedRealTime(__int64
&t
)
211 long long System::physicalMemory()
213 #if !defined(__CYGWIN__) || (_WIN32_WINNT >= 0x0500)
214 MEMORYSTATUSEX statex
;
215 statex
.dwLength
= sizeof (statex
);
217 GlobalMemoryStatusEx (&statex
);
218 return statex
.ullTotalPhys
;
221 stat
.dwLength
= sizeof (stat
);
223 GlobalMemoryStatus (&stat
);
224 return stat
.dwTotalPhys
;
228 long long System::availablePhysicalMemory()
230 #if !defined(__CYGWIN__) || (_WIN32_WINNT >= 0x0500)
231 MEMORYSTATUSEX statex
;
232 statex
.dwLength
= sizeof (statex
);
234 GlobalMemoryStatusEx (&statex
);
235 return statex
.ullAvailPhys
;
238 stat
.dwLength
= sizeof (stat
);
240 GlobalMemoryStatus (&stat
);
241 return stat
.dwAvailPhys
;
245 size_t System::memoryUsedByProcess()
247 PROCESS_MEMORY_COUNTERS pmc
;
248 GetProcessMemoryInfo(GetCurrentProcess(), &pmc
, sizeof(pmc
));
250 return pmc
.WorkingSetSize
;
253 size_t System::peakMemoryUsedByProcess()
255 PROCESS_MEMORY_COUNTERS pmc
;
256 GetProcessMemoryInfo(GetCurrentProcess(), &pmc
, sizeof(pmc
));
258 return pmc
.PeakWorkingSetSize
;
263 long long System::physicalMemory()
265 unsigned long long value
;
266 size_t size
= sizeof( value
);
267 if (sysctlbyname("hw.memsize", &value
, &size
, NULL
, 0) !=-1)
273 long long System::availablePhysicalMemory()
275 unsigned long long pageSize
;
277 size_t size
= sizeof( pageSize
);
278 sysctlbyname("hw.pagesize", &pageSize
, &size
, NULL
, 0);
280 vm_statistics_data_t vm_stat
;
281 int count
= ((mach_msg_type_number_t
) (sizeof(vm_statistics_data_t
)/sizeof(integer_t
)));
282 host_statistics(mach_host_self(), HOST_VM_INFO
, (integer_t
*)&vm_stat
, (mach_msg_type_number_t
*)&count
);
283 result
= (unsigned long long)(vm_stat
.free_count
+ vm_stat
.inactive_count
) * pageSize
;
288 size_t System::memoryUsedByProcess()
290 /*int pid = getpid();
291 static char filename[32];
292 sprintf(filename, 32, "/proc/%d/statm", pid);
294 int fd = open(filename, O_RDONLY, 0);
295 if(fd==-1) OGDF_THROW(Exception);
297 static char sbuf[256];
298 sbuf[read(fd, sbuf, sizeof(sbuf) - 1)] = 0;
301 long size, resident, share, trs, lrs, drs, dt;
302 sscanf(sbuf, "%ld %ld %ld %ld %ld %ld %ld",
303 &size, // total program size (in pages)
304 &resident, // number of resident set (non-swapped) pages (4k)
305 &share, // number of pages of shared (mmap'd) memory
306 &trs, // text resident set size
307 &lrs, // shared-lib resident set size
308 &drs, // data resident set size
311 return resident*4*1024;*/
317 long long System::physicalMemory()
319 return (long long)(sysconf(_SC_PHYS_PAGES
)) * sysconf(_SC_PAGESIZE
);
322 long long System::availablePhysicalMemory()
324 return (long long)(sysconf(_SC_AVPHYS_PAGES
)) * sysconf(_SC_PAGESIZE
);
327 size_t System::memoryUsedByProcess()
330 static char filename
[32];
331 sprintf(filename
, 32, "/proc/%d/statm", pid
);
333 int fd
= open(filename
, O_RDONLY
, 0);
334 if(fd
==-1) OGDF_THROW(Exception
);
336 static char sbuf
[256];
337 sbuf
[read(fd
, sbuf
, sizeof(sbuf
) - 1)] = 0;
340 long size
, resident
, share
, trs
, lrs
, drs
, dt
;
341 sscanf(sbuf
, "%ld %ld %ld %ld %ld %ld %ld",
342 &size
, // total program size (in pages)
343 &resident
, // number of resident set (non-swapped) pages (4k)
344 &share
, // number of pages of shared (mmap'd) memory
345 &trs
, // text resident set size
346 &lrs
, // shared-lib resident set size
347 &drs
, // data resident set size
350 return resident
*4*1024;
356 #ifdef OGDF_SYSTEM_WINDOWS
358 size_t System::memoryAllocatedByMalloc()
362 hinfo
._pentry
= NULL
;
365 while((heapstatus
= _heapwalk(&hinfo
)) == _HEAPOK
)
367 if(hinfo
._useflag
== _USEDENTRY
)
368 allocMem
+= hinfo
._size
;
374 size_t System::memoryInFreelistOfMalloc()
378 hinfo
._pentry
= NULL
;
381 while((heapstatus
= _heapwalk(&hinfo
)) == _HEAPOK
)
383 if(hinfo
._useflag
== _FREEENTRY
)
384 allocMem
+= hinfo
._size
;
392 size_t System::memoryAllocatedByMalloc()
394 return mstats().chunks_used
;
397 size_t System::memoryInFreelistOfMalloc()
399 return mstats().chunks_free
;
403 size_t System::memoryAllocatedByMalloc()
405 return mallinfo().uordblks
;
408 size_t System::memoryInFreelistOfMalloc()
410 return mallinfo().fordblks
;
415 #if !defined(OGDF_SYSTEM_WINDOWS) && !defined(__CYGWIN__)
416 __int64
System::usedRealTime(__int64
&t
)
420 gettimeofday(&tv
, 0);
421 t
= __int64(tv
.tv_sec
) * 1000 + tv
.tv_usec
/1000;
427 size_t System::memoryAllocatedByMemoryManager()
429 return PoolMemoryAllocator::memoryAllocatedInBlocks();
432 size_t System::memoryInGlobalFreeListOfMemoryManager()
434 return PoolMemoryAllocator::memoryInGlobalFreeList();
437 size_t System::memoryInThreadFreeListOfMemoryManager()
439 return PoolMemoryAllocator::memoryInThreadFreeList();