CppBenchmark  1.0.4.0
C++ Benchmark Library
environment.cpp
Go to the documentation of this file.
1 
10 
11 #include <chrono>
12 #include <codecvt>
13 #include <cstring>
14 #include <locale>
15 #include <sstream>
16 
17 #if defined(__APPLE__)
18 #include <sys/sysctl.h>
19 #elif defined(unix) || defined(__unix) || defined(__unix__)
20 #include <sys/stat.h>
21 #include <sys/utsname.h>
22 #include <fstream>
23 #include <regex>
24 #endif
25 #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
26 #include <windows.h>
27 #include <winternl.h>
28 #define STATUS_SUCCESS 0x00000000
29 #endif
30 
31 namespace CppBenchmark {
32 
34 {
35  return !Is64BitOS();
36 }
37 
39 {
40 #if defined(__APPLE__)
41  return true;
42 #elif defined(linux) || defined(__linux) || defined(__linux__)
43  struct stat buffer;
44  return (stat("/lib64/ld-linux-x86-64.so.2", &buffer) == 0);
45 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
46 #if defined(_WIN64)
47  return true;
48 #elif defined(_WIN32) || defined(__CYGWIN__)
49  BOOL bWow64Process = FALSE;
50  return IsWow64Process(GetCurrentProcess(), &bWow64Process) && bWow64Process;
51 #endif
52 #else
53  #error Unsupported platform
54 #endif
55 }
56 
58 {
59  return !Is64BitProcess();
60 }
61 
63 {
64 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
65 #if defined(__x86_64__) || defined(__amd64__) || defined(__aarch64__) || defined(__ia64__) || defined(__ppc64__)
66  return true;
67 #else
68  return false;
69 #endif
70 #elif defined(_WIN32) || defined(_WIN64)
71 #if defined(_WIN64)
72  return true;
73 #elif defined(_WIN32)
74  return false;
75 #endif
76 #else
77  #error Unsupported platform
78 #endif
79 }
80 
82 {
83  return !IsRelease();
84 }
85 
87 {
88 #if defined(NDEBUG)
89  return true;
90 #else
91  return false;
92 #endif
93 }
94 
96 {
97  char16_t test = 0x0102;
98  return ((char*)&test)[0] == 0x01;
99 }
100 
102 {
103  char16_t test = 0x0102;
104  return ((char*)&test)[0] == 0x02;
105 }
106 
108 {
109 #if defined(__APPLE__)
110  char result[1024];
111  size_t size = sizeof(result);
112  if (sysctlbyname("kern.osrelease", result, &size, nullptr, 0) == 0)
113  return result;
114 
115  return "<apple>";
116 #elif defined(__CYGWIN__)
117  struct utsname name;
118  if (uname(&name) == 0)
119  {
120  std::string result(name.sysname);
121  result.append(" ");
122  result.append(name.release);
123  result.append(" ");
124  result.append(name.version);
125  return result;
126  }
127 
128  return "<cygwin>";
129 #elif defined(linux) || defined(__linux) || defined(__linux__)
130  static std::regex pattern("DISTRIB_DESCRIPTION=\"(.*)\"");
131 
132  std::string line;
133  std::ifstream stream("/etc/lsb-release");
134  while (getline(stream, line))
135  {
136  std::smatch matches;
137  if (std::regex_match(line, matches, pattern))
138  return matches[1];
139  }
140 
141  return "<linux>";
142 #elif defined(_WIN32) || defined(_WIN64)
143  static NTSTATUS(__stdcall *RtlGetVersion)(OUT PRTL_OSVERSIONINFOEXW lpVersionInformation) = (NTSTATUS(__stdcall*)(PRTL_OSVERSIONINFOEXW))GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion");
144  static void(__stdcall *GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall*)(LPSYSTEM_INFO))GetProcAddress(GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo");
145  static BOOL(__stdcall *GetProductInfo)(IN DWORD dwOSMajorVersion, IN DWORD dwOSMinorVersion, IN DWORD dwSpMajorVersion, IN DWORD dwSpMinorVersion, OUT PDWORD pdwReturnedProductType) = (BOOL(__stdcall*)(DWORD, DWORD, DWORD, DWORD, PDWORD))GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProductInfo");
146 
147  OSVERSIONINFOEXW osvi;
148  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXW));
149  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
150 
151  if (RtlGetVersion != nullptr)
152  {
153  NTSTATUS ntRtlGetVersionStatus = RtlGetVersion(&osvi);
154  if (ntRtlGetVersionStatus != STATUS_SUCCESS)
155  return "<windows>";
156  }
157  else
158  {
159 #if defined(_MSC_VER)
160 #pragma warning(push)
161 #pragma warning(disable: 4996) // C4996: 'function': was declared deprecated
162 #endif
163  BOOL bOsVersionInfoEx = GetVersionExW((OSVERSIONINFOW*)&osvi);
164  if (bOsVersionInfoEx == 0)
165  return "<windows>";
166 #if defined(_MSC_VER)
167 #pragma warning(pop)
168 #endif
169  }
170 
171  SYSTEM_INFO si;
172  ZeroMemory(&si, sizeof(SYSTEM_INFO));
173 
174  if (GetNativeSystemInfo != nullptr)
175  GetNativeSystemInfo(&si);
176  else
177  GetSystemInfo(&si);
178 
179  if ((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) || (osvi.dwMajorVersion <= 4))
180  {
181  return "<windows>";
182  }
183 
184  std::stringstream os;
185 
186  // Windows version
187  os << "Microsoft ";
188  if (osvi.dwMajorVersion >= 6)
189  {
190  if (osvi.dwMajorVersion == 10)
191  {
192  if (osvi.dwMinorVersion == 0)
193  {
194  if (osvi.wProductType == VER_NT_WORKSTATION)
195  {
196  if (osvi.dwBuildNumber >= 22000)
197  os << "Windows 11 ";
198  else
199  os << "Windows 10 ";
200  }
201  else
202  {
203  if (osvi.dwBuildNumber >= 20348)
204  os << "Windows Server 2022 ";
205  else if (osvi.dwBuildNumber >= 17763)
206  os << "Windows Server 2019 ";
207  else
208  os << "Windows Server 2016 ";
209  }
210  }
211  }
212  else if (osvi.dwMajorVersion == 6)
213  {
214  if (osvi.dwMinorVersion == 3)
215  {
216  if (osvi.wProductType == VER_NT_WORKSTATION)
217  os << "Windows 8.1 ";
218  else
219  os << "Windows Server 2012 R2 ";
220  }
221  else if (osvi.dwMinorVersion == 2)
222  {
223  if (osvi.wProductType == VER_NT_WORKSTATION)
224  os << "Windows 8 ";
225  else
226  os << "Windows Server 2012 ";
227  }
228  else if (osvi.dwMinorVersion == 1)
229  {
230  if (osvi.wProductType == VER_NT_WORKSTATION)
231  os << "Windows 7 ";
232  else
233  os << "Windows Server 2008 R2 ";
234  }
235  else if (osvi.dwMinorVersion == 0)
236  {
237  if (osvi.wProductType == VER_NT_WORKSTATION)
238  os << "Windows Vista ";
239  else
240  os << "Windows Server 2008 ";
241  }
242  }
243 
244  DWORD dwType;
245  if ((GetProductInfo != nullptr) && GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType))
246  {
247  switch (dwType)
248  {
249  case PRODUCT_ULTIMATE:
250  os << "Ultimate Edition";
251  break;
252  case PRODUCT_PROFESSIONAL:
253  os << "Professional";
254  break;
255  case PRODUCT_HOME_PREMIUM:
256  os << "Home Premium Edition";
257  break;
258  case PRODUCT_HOME_BASIC:
259  os << "Home Basic Edition";
260  break;
261  case PRODUCT_ENTERPRISE:
262  os << "Enterprise Edition";
263  break;
264  case PRODUCT_BUSINESS:
265  os << "Business Edition";
266  break;
267  case PRODUCT_STARTER:
268  os << "Starter Edition";
269  break;
270  case PRODUCT_CLUSTER_SERVER:
271  os << "Cluster Server Edition";
272  break;
273  case PRODUCT_DATACENTER_SERVER:
274  os << "Datacenter Edition";
275  break;
276  case PRODUCT_DATACENTER_SERVER_CORE:
277  os << "Datacenter Edition (core installation)";
278  break;
279  case PRODUCT_ENTERPRISE_SERVER:
280  os << "Enterprise Edition";
281  break;
282  case PRODUCT_ENTERPRISE_SERVER_CORE:
283  os << "Enterprise Edition (core installation)";
284  break;
285  case PRODUCT_ENTERPRISE_SERVER_IA64:
286  os << "Enterprise Edition for Itanium-based Systems";
287  break;
288  case PRODUCT_SMALLBUSINESS_SERVER:
289  os << "Small Business Server";
290  break;
291  case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
292  os << "Small Business Server Premium Edition";
293  break;
294  case PRODUCT_STANDARD_SERVER:
295  os << "Standard Edition";
296  break;
297  case PRODUCT_STANDARD_SERVER_CORE:
298  os << "Standard Edition (core installation)";
299  break;
300  case PRODUCT_WEB_SERVER:
301  os << "Web Server Edition";
302  break;
303  }
304  }
305  }
306  else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2))
307  {
308  if (GetSystemMetrics(SM_SERVERR2))
309  os << "Windows Server 2003 R2, ";
310  else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
311  os << "Windows Storage Server 2003";
312  else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER)
313  os << "Windows Home Server";
314  else if ((osvi.wProductType == VER_NT_WORKSTATION) && (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64))
315  os << "Windows XP Professional x64 Edition";
316  else
317  os << "Windows Server 2003, ";
318  if (osvi.wProductType != VER_NT_WORKSTATION)
319  {
320  if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
321  {
322  if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
323  os << "Datacenter Edition for Itanium-based Systems";
324  else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
325  os << "Enterprise Edition for Itanium-based Systems";
326  }
327  else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
328  {
329  if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
330  os << "Datacenter x64 Edition";
331  else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
332  os << "Enterprise x64 Edition";
333  else
334  os << "Standard x64 Edition";
335  }
336  else
337  {
338  if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
339  os << "Compute Cluster Edition";
340  else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
341  os << "Datacenter Edition";
342  else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
343  os << "Enterprise Edition";
344  else if (osvi.wSuiteMask & VER_SUITE_BLADE)
345  os << "Web Edition";
346  else
347  os << "Standard Edition";
348  }
349  }
350  }
351  else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1))
352  {
353  os << "Windows XP ";
354  if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
355  os << "Home Edition";
356  else
357  os << "Professional";
358  }
359  else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0))
360  {
361  os << "Windows 2000 ";
362  if (osvi.wProductType == VER_NT_WORKSTATION)
363  os << "Professional";
364  else
365  {
366  if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
367  os << "Datacenter Server";
368  else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
369  os << "Advanced Server";
370  else
371  os << "Server";
372  }
373  }
374 
375  // Windows Service Pack version
376  std::wstring sp_version(osvi.szCSDVersion);
377  std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
378  if (std::wcslen(osvi.szCSDVersion) > 0)
379  os << " " << convert.to_bytes(sp_version.data(), sp_version.data() + sp_version.size());
380 
381  // Windows build
382  os << " (build " << osvi.dwBuildNumber << ")";
383 
384  // Windows architecture
385  if (osvi.dwMajorVersion >= 6)
386  {
387  if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
388  os << ", 32-bit";
389  else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
390  os << ", 64-bit";
391  else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
392  os << ", Intel Itanium";
393  else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM)
394  os << ", ARM";
395 #if !defined(__MINGW32__) && !defined(__MINGW64__)
396  else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)
397  os << ", ARM64";
398 #endif
399  }
400 
401  return os.str();
402 #else
403  #error Unsupported platform
404 #endif
405 }
406 
407 std::string Environment::EndLine()
408 {
409 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
410  return "\n";
411 #elif defined(_WIN32) || defined(_WIN64)
412  return "\r\n";
413 #else
414  #error Unsupported platform
415 #endif
416 }
417 
419 {
420  return "\n";
421 }
422 
424 {
425  return "\r\n";
426 }
427 
429 {
430  return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
431 }
432 
433 } // namespace CppBenchmark
static bool IsDebug()
Is compiled in debug mode?
Definition: environment.cpp:81
static std::string OSVersion()
Get OS version string.
static bool IsRelease()
Is compiled in release mode?
Definition: environment.cpp:86
static time_t Timestamp()
Get the current time in seconds.
static bool Is64BitProcess()
Is 64-bit running process?
Definition: environment.cpp:62
static bool IsLittleEndian()
Is little-endian system?
static std::string WindowsEndLine()
Get Windows text end line separator.
static std::string EndLine()
Get text end line separator.
static std::string UnixEndLine()
Get Unix text end line separator.
static bool Is64BitOS()
Is 64-bit OS?
Definition: environment.cpp:38
static bool Is32BitOS()
Is 32-bit OS?
Definition: environment.cpp:33
static bool Is32BitProcess()
Is 32-bit running process?
Definition: environment.cpp:57
static bool IsBigEndian()
Is big-endian system?
Definition: environment.cpp:95
Environment management definition.
C++ Benchmark project definitions.
Definition: barrier.h:15