Don't import ogdf namespace
[TortoiseGit.git] / ext / OGDF / src / basic / System.cpp
blobc5b5fb23599608eee87383c5985f120545064319
1 /*
2 * $Revision: 2633 $
4 * last checkin:
5 * $Author: gutwenger $
6 * $Date: 2012-07-18 09:09:28 +0200 (Mi, 18. Jul 2012) $
7 ***************************************************************/
9 /** \file
10 * \brief Implementation of System class.
12 * \author Carsten Gutwenger
14 * \par License:
15 * This file is part of the Open Graph Drawing Framework (OGDF).
17 * \par
18 * Copyright (C)<br>
19 * See README.txt in the root directory of the OGDF installation for details.
21 * \par
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
26 * for details.
28 * \par
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.
34 * \par
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>
46 #ifdef __APPLE__
47 #include <stdlib.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)
56 #include <malloc.h>
57 #endif
59 #if defined(OGDF_SYSTEM_WINDOWS) || defined(__CYGWIN__)
60 #include <Psapi.h>
61 #endif
63 #ifdef _MSC_VER
64 #include <intrin.h>
66 #elif defined(OGDF_SYSTEM_UNIX) || (defined(__MINGW32__) && !defined(__MINGW64__))
67 #include <unistd.h>
68 #include <fcntl.h>
69 #include <sys/time.h>
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"
80 "cpuid \n\t"
81 "xchgl %%ebx,%0\n\t"
82 : "+r" (b), "=a" (a), "=c" (c), "=d" (d)
83 : "1" (infoType), "2" (c));
84 #else
85 // not supported on other systems!
86 a = b = c = d = 0;
87 #endif
89 CPUInfo[0] = a;
90 CPUInfo[1] = b;
91 CPUInfo[2] = c;
92 CPUInfo[3] = d;
94 #endif
97 namespace ogdf {
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;
108 #endif
111 void System::init()
113 s_cpuFeatures = 0;
114 s_cacheSize = 0;
115 s_cacheLine = 0;
117 // currently not working for shared libs on Linux
118 #if !defined(OGDF_DLL) || !defined(OGDF_SYSTEM_UNIX)
120 int CPUInfo[4] = {-1};
121 __cpuid(CPUInfo, 0);
123 unsigned int nIds = CPUInfo[0];
124 if(nIds >= 1)
126 __cpuid(CPUInfo, 1);
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;
166 else
167 s_pageSize = 0;
169 if (sysctlbyname("hw.ncpu", &value, &size, NULL, 0) !=-1)
170 s_numberOfProcessors = (int)value;
171 else
172 s_numberOfProcessors = 1;
174 #elif defined(OGDF_SYSTEM_UNIX)
175 s_pageSize = sysconf(_SC_PAGESIZE);
176 s_numberOfProcessors = (int)sysconf(_SC_NPROCESSORS_CONF);
178 #else
179 s_pageSize = 0; // just a placeholder!!!
180 s_numberOfProcessors = 1; // just a placeholder!!!
181 #endif
183 #endif
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)
205 __int64 tStart = t;
206 t = GetTickCount();
207 return t - tStart;
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;
219 #else
220 MEMORYSTATUS stat;
221 stat.dwLength = sizeof (stat);
223 GlobalMemoryStatus (&stat);
224 return stat.dwTotalPhys;
225 #endif
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;
236 #else
237 MEMORYSTATUS stat;
238 stat.dwLength = sizeof (stat);
240 GlobalMemoryStatus (&stat);
241 return stat.dwAvailPhys;
242 #endif
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;
261 #elif __APPLE__
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)
268 return value;
269 else
270 return 0;
273 long long System::availablePhysicalMemory()
275 unsigned long long pageSize;
276 long long result;
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;
284 return result;
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;
299 close(fd);
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
309 &dt); // dirty pages
311 return resident*4*1024;*/
312 return 0;
315 #else
316 // LINUX, NOT MAC OS
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()
329 int pid = getpid();
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;
338 close(fd);
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
348 &dt); // dirty pages
350 return resident*4*1024;
353 #endif
356 #ifdef OGDF_SYSTEM_WINDOWS
358 size_t System::memoryAllocatedByMalloc()
360 _HEAPINFO hinfo;
361 int heapstatus;
362 hinfo._pentry = NULL;
364 size_t allocMem = 0;
365 while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK)
367 if(hinfo._useflag == _USEDENTRY)
368 allocMem += hinfo._size;
371 return allocMem;
374 size_t System::memoryInFreelistOfMalloc()
376 _HEAPINFO hinfo;
377 int heapstatus;
378 hinfo._pentry = NULL;
380 size_t allocMem = 0;
381 while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK)
383 if(hinfo._useflag == _FREEENTRY)
384 allocMem += hinfo._size;
387 return allocMem;
390 #elif __APPLE__
392 size_t System::memoryAllocatedByMalloc()
394 return mstats().chunks_used;
397 size_t System::memoryInFreelistOfMalloc()
399 return mstats().chunks_free;
401 #else
403 size_t System::memoryAllocatedByMalloc()
405 return mallinfo().uordblks;
408 size_t System::memoryInFreelistOfMalloc()
410 return mallinfo().fordblks;
413 #endif
415 #if !defined(OGDF_SYSTEM_WINDOWS) && !defined(__CYGWIN__)
416 __int64 System::usedRealTime(__int64 &t)
418 __int64 tStart = t;
419 timeval tv;
420 gettimeofday(&tv, 0);
421 t = __int64(tv.tv_sec) * 1000 + tv.tv_usec/1000;
422 return t - tStart;
424 #endif
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();
443 } // namespace ogdf