Oolite 1.91.0.7745-260117-205bce7
Loading...
Searching...
No Matches
OOCPUInfo.m
Go to the documentation of this file.
1/*
2
3OOCPUInfo.m
4
5Oolite
6Copyright (C) 2004-2013 Giles C Williams and contributors
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21MA 02110-1301, USA.
22
23*/
24
25#import "OOCPUInfo.h"
26#include <stdlib.h>
27
28#if OOLITE_MAC_OS_X
29#include <sys/sysctl.h>
30#elif (OOLITE_LINUX || OOLITE_WINDOWS)
31// Workaround for clang/glibc incompatibility.
32#if !OOLITE_HAVE_CLANG
33#define __block __glibc_block
34#endif
35#include <unistd.h>
36#if !OOLITE_HAVE_CLANG
37#undef __block
38#endif
39#endif
40
41
42#if 0
43// Confirm settings
44#if OOLITE_BIG_ENDIAN
45#warning Big-endian.
46#endif
47#if OOLITE_LITTLE_ENDIAN
48#warning Little-endian.
49#endif
50#if OOLITE_NATIVE_64_BIT
51#warning 64-bit.
52#else
53#warning 32-bit.
54#endif
55#endif
56
57
58static BOOL sInited = NO;
59
60
61static NSUInteger sNumberOfCPUs = 0; // Yes, really 0.
62
63
64void OOCPUInfoInit(void)
65{
66 if (sInited) return;
67
68 // Verify correctness of endian macros
69 uint8_t endianTag[4] = {0x12, 0x34, 0x56, 0x78};
70
71#if OOLITE_BIG_ENDIAN
72 if (*(uint32_t*)endianTag != 0x12345678)
73 {
74 OOLog(@"cpuInfo.endianTest.failed", @"%@", @"OOLITE_BIG_ENDIAN is set, but the system is not big-endian -- aborting.");
75 exit(EXIT_FAILURE);
76 }
77#endif
78
79#if OOLITE_LITTLE_ENDIAN
80 if (*(uint32_t*)endianTag != 0x78563412)
81 {
82 OOLog(@"cpuInfo.endianTest.failed", @"%@", @"OOLITE_LITTLE_ENDIAN is set, but the system is not little-endian -- aborting.");
83 exit(EXIT_FAILURE);
84 }
85#endif
86
87 // Count processors
88#if OOLITE_MAC_OS_X
89 sNumberOfCPUs = [[NSProcessInfo processInfo] processorCount];
90#elif OOLITE_WINDOWS
91 SYSTEM_INFO sysInfo;
92
93 GetSystemInfo(&sysInfo);
94 sNumberOfCPUs = sysInfo.dwNumberOfProcessors;
95#elif defined _SC_NPROCESSORS_ONLN
96 sNumberOfCPUs = sysconf(_SC_NPROCESSORS_ONLN);
97#else
98 #warning Do not know how to find number of CPUs on this architecture.
99#endif // OS selection
100
101 sInited = YES;
102}
103
104
105NSUInteger OOCPUCount(void)
106{
107 if (!sInited) OOCPUInfoInit();
108 return (sNumberOfCPUs != 0) ? sNumberOfCPUs : 1;
109}
110
111
112#if (OOLITE_WINDOWS || OOLITE_LINUX)
113 #if OOLITE_LINUX
114 #define OO_GNU_INLINE __attribute__((gnu_inline))
115 #else
116 #define OO_GNU_INLINE
117 #endif
118/*
119Taken straight out of the x64 gcc's __cpuid because our 32-bit compiler does not define it
120*/
121inline OO_GNU_INLINE void OOCPUID(int CPUInfo[4], int InfoType)
122{
123 __asm__ __volatile__ (
124/* Fixes building on 32-bit systems where %EBX is used for the GOT pointer */
125#if (OOLITE_LINUX && !defined __LP64__)
126 " pushl %%ebx\n"
127 " cpuid\n"
128 " mov %%ebx, %1\n"
129 " popl %%ebx"
130 : "=a" (CPUInfo [0]), "=r" (CPUInfo [1]), "=c" (CPUInfo [2]), "=d" (CPUInfo [3])
131#else
132 "cpuid"
133 : "=a" (CPUInfo [0]), "=b" (CPUInfo [1]), "=c" (CPUInfo [2]), "=d" (CPUInfo [3])
134#endif
135 : "a" (InfoType));
136}
137
138
139NSString* OOCPUDescription(void)
140{
141 // This code taken from https://stackoverflow.com/questions/850774
142 int CPUInfo[4] = {-1};
143 unsigned nExIds, i = 0;
144 char CPUBrandString[0x40];
145 // Get the information associated with each extended ID.
146 OOCPUID(CPUInfo, 0x80000000);
147 nExIds = CPUInfo[0];
148 for (i=0x80000000; i<=nExIds; ++i)
149 {
150 OOCPUID(CPUInfo, i);
151 // Interpret CPU brand string
152 if (i == 0x80000002)
153 memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
154 else if (i == 0x80000003)
155 memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
156 else if (i == 0x80000004)
157 memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
158 }
159 return [NSString stringWithCString:CPUBrandString];
160}
161
162
163OOMemoryStatus OOSystemMemoryStatus(void)
164{
165 const unsigned int toMegabyte = 1024 * 1024;
166
167 OOMemoryStatus systemMemoryStatus;
168 memset(&systemMemoryStatus, 0, sizeof(systemMemoryStatus));
169
170#if OOLITE_WINDOWS
171 MEMORYSTATUSEX memStatus;
172 memStatus.dwLength = sizeof(memStatus);
173 if(GlobalMemoryStatusEx(&memStatus))
174 {
175 // return memory size in MB
176 systemMemoryStatus.ooPhysicalMemory = memStatus.ullTotalPhys / toMegabyte;
177 systemMemoryStatus.ooAvailableMemory = memStatus.ullAvailPhys / toMegabyte;
178 }
179#else
180 struct sysinfo si;
181 sysinfo(&si);
182 systemMemoryStatus.ooPhysicalMemory = (unsigned long long)(si.totalram / toMegabyte);
183 systemMemoryStatus.ooAvailableMemory = (unsigned long long)(si.freeram / toMegabyte);
184#endif
185
186 return systemMemoryStatus;
187}
188#endif //(OOLITE_WINDOWS || OOLITE_LINUX)
189
190
191#if OOLITE_WINDOWS
192NSString* operatingSystemFullVersion(void)
193{
194 OSVERSIONINFOW osver;
195 char outUBRString[65] = "";
196
197 osver.dwOSVersionInfoSize = sizeof(osver);
198 GetVersionExW (&osver);
199
200 // get the Update Build Revision from the Registry
201 HKEY hKey;
202 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
203 {
204 DWORD dwUBRSize = sizeof(DWORD);
205 DWORD dwUBR = 0;
206 if (RegQueryValueEx(hKey,"UBR", NULL, NULL, (BYTE*)&dwUBR, &dwUBRSize) == ERROR_SUCCESS)
207 {
208 char strUBR[64] = "";
209 ltoa(dwUBR, strUBR, 10);
210 strcpy(outUBRString, ".");
211 strcat(outUBRString, strUBR);
212 }
213 }
214
215 return [NSString stringWithFormat:@"%lu.%lu.%lu%s %S",
216 osver.dwMajorVersion, osver.dwMinorVersion, osver.dwBuildNumber, outUBRString, (const WCHAR *)osver.szCSDVersion];
217}
218
219/*
220is64bitSystem: Detect operating system bitness. This function is based mainly on code by Mark S. Kolich, as
221seen in http://mark.koli.ch/2009/10/reliably-checking-os-bitness-32-or-64-bit-on-windows-with-a-tiny-c-app.html
222*/
223BOOL is64BitSystem(void)
224{
225 #if defined(_WIN64)
226 // if we have been compiled as a 64-bit app and we are running, we are obviously on a 64-bit system
227 return YES;
228 #else
229 BOOL is64Bit = NO;
230
231 IW64PFP IW64P = (IW64PFP)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
232 if(IW64P != NULL)
233 {
234 IW64P(GetCurrentProcess(), &is64Bit);
235 }
236
237 return is64Bit;
238 #endif
239}
240#endif // OOLITE_WINDOWS
void OOCPUInfoInit(void)
Definition OOCPUInfo.m:64
static NSUInteger sNumberOfCPUs
Definition OOCPUInfo.m:61
NSUInteger OOCPUCount(void)
Definition OOCPUInfo.m:105
#define OOLITE_LINUX
Definition OOCocoa.h:263
#define OOLog(class, format,...)
Definition OOLogging.h:88
static BOOL sInited
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque