• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "util/sys_info.h"
6 
7 #include "base/logging.h"
8 #include "util/build_config.h"
9 
10 #if defined(OS_POSIX)
11 #include <sys/utsname.h>
12 #include <unistd.h>
13 #endif
14 
15 #if defined(OS_WIN)
16 #include <windows.h>
17 #include "base/win/registry.h"
18 #endif
19 
IsLongPathsSupportEnabled()20 bool IsLongPathsSupportEnabled() {
21 #if defined(OS_WIN)
22   struct LongPathSupport {
23     LongPathSupport() {
24       // Probe ntdll.dll for RtlAreLongPathsEnabled, and call it if it exists.
25       HINSTANCE ntdll_lib = GetModuleHandleW(L"ntdll");
26       if (ntdll_lib) {
27         using FunctionType = BOOLEAN(WINAPI*)();
28         auto func_ptr = reinterpret_cast<FunctionType>(
29             GetProcAddress(ntdll_lib, "RtlAreLongPathsEnabled"));
30         if (func_ptr) {
31           supported = func_ptr();
32           return;
33         }
34       }
35 
36       // If the ntdll approach failed, the registry approach is still reliable,
37       // because the manifest should've always be linked with gn.exe in Windows.
38       const char16_t key_name[] = uR"(SYSTEM\CurrentControlSet\Control\FileSystem)";
39       const char16_t value_name[] = u"LongPathsEnabled";
40 
41       base::win::RegKey key(HKEY_LOCAL_MACHINE, key_name, KEY_READ);
42       DWORD value;
43       if (key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
44         supported = value == 1;
45       }
46     }
47 
48     bool supported = false;
49   };
50 
51   static LongPathSupport s_long_paths;  // constructed lazily
52   return s_long_paths.supported;
53 #else
54   return true;
55 #endif
56 }
57 
OperatingSystemArchitecture()58 std::string OperatingSystemArchitecture() {
59 #if defined(OS_POSIX)
60   struct utsname info;
61   if (uname(&info) < 0) {
62     NOTREACHED();
63     return std::string();
64   }
65   std::string arch(info.machine);
66   std::string os(info.sysname);
67   if (arch == "i386" || arch == "i486" || arch == "i586" || arch == "i686") {
68     arch = "x86";
69   } else if (arch == "i86pc") {
70     // Solaris and illumos systems report 'i86pc' (an Intel x86 PC) as their
71     // machine for both 32-bit and 64-bit x86 systems.  Considering the rarity
72     // of 32-bit systems at this point, it is safe to assume 64-bit.
73     arch = "x86_64";
74   } else if (arch == "amd64") {
75     arch = "x86_64";
76   } else if (os == "AIX" || os == "OS400") {
77     arch = "ppc64";
78   } else if (std::string(info.sysname) == "OS/390") {
79     arch = "s390x";
80   }
81   return arch;
82 #elif defined(OS_WIN)
83   SYSTEM_INFO system_info = {};
84   ::GetNativeSystemInfo(&system_info);
85   switch (system_info.wProcessorArchitecture) {
86     case PROCESSOR_ARCHITECTURE_INTEL:
87       return "x86";
88     case PROCESSOR_ARCHITECTURE_AMD64:
89       return "x86_64";
90     case PROCESSOR_ARCHITECTURE_IA64:
91       return "ia64";
92   }
93   return std::string();
94 #else
95 #error
96 #endif
97 }
98 
NumberOfProcessors()99 int NumberOfProcessors() {
100 #if defined(OS_ZOS)
101   return __get_num_online_cpus();
102 
103 #elif defined(OS_POSIX)
104   // sysconf returns the number of "logical" (not "physical") processors on both
105   // Mac and Linux.  So we get the number of max available "logical" processors.
106   //
107   // Note that the number of "currently online" processors may be fewer than the
108   // returned value of NumberOfProcessors(). On some platforms, the kernel may
109   // make some processors offline intermittently, to save power when system
110   // loading is low.
111   //
112   // One common use case that needs to know the processor count is to create
113   // optimal number of threads for optimization. It should make plan according
114   // to the number of "max available" processors instead of "currently online"
115   // ones. The kernel should be smart enough to make all processors online when
116   // it has sufficient number of threads waiting to run.
117   long res = sysconf(_SC_NPROCESSORS_CONF);
118   if (res == -1) {
119     NOTREACHED();
120     return 1;
121   }
122 
123   return static_cast<int>(res);
124 #elif defined(OS_WIN)
125   // On machines with more than 64 logical processors this will not return the
126   // full number of processors. Instead it will return the number of processors
127   // in one processor group - something smaller than 65. However this is okay
128   // because gn doesn't parallelize well beyond 10-20 threads - it starts to run
129   // slower.
130   SYSTEM_INFO system_info = {};
131   ::GetNativeSystemInfo(&system_info);
132   return system_info.dwNumberOfProcessors;
133 #else
134 #error
135 #endif
136 }
137