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