1 // Created on: 2014-08-19
2 // Created by: Alexander Zaikin
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 2013-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <OSD_Parallel.hxx>
23 #include <sys/types.h>
26 #include <sys/processor.h>
27 #include <sys/procset.h>
35 #if defined(_WIN32) && !defined(OCCT_UWP)
36 //! For a 64-bit app running under 64-bit Windows, this is FALSE.
39 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE , PBOOL);
40 BOOL bIsWow64 = FALSE;
42 HMODULE aKern32Module = GetModuleHandleW(L"kernel32");
43 LPFN_ISWOW64PROCESS aFunIsWow64 = (aKern32Module == NULL) ? (LPFN_ISWOW64PROCESS )NULL
44 : (LPFN_ISWOW64PROCESS)GetProcAddress(aKern32Module, "IsWow64Process");
46 return aFunIsWow64 != NULL &&
47 aFunIsWow64(GetCurrentProcess(), &bIsWow64) &&
51 #elif defined(__ANDROID__)
53 //! Simple number parser.
54 static const char* parseNumber (int& theResult,
57 const int theBase = 10)
59 const char* aCharIter = theInput;
61 while (aCharIter < theLimit)
63 int aDigit = (*aCharIter - '0');
64 if ((unsigned int )aDigit >= 10U)
66 aDigit = (*aCharIter - 'a');
67 if ((unsigned int )aDigit >= 6U)
69 aDigit = (*aCharIter - 'A');
71 if ((unsigned int )aDigit >= 6U)
77 if (aDigit >= theBase)
81 aValue = aValue * theBase + aDigit;
84 if (aCharIter == theInput)
93 //! Read CPUs mask from sysfs.
94 static uint32_t readCpuMask (const char* thePath)
96 FILE* aFileHandle = fopen (thePath, "rb");
97 if (aFileHandle == NULL)
102 fseek (aFileHandle, 0, SEEK_END);
103 long aFileLen = ftell (aFileHandle);
106 fclose (aFileHandle);
110 char* aBuffer = (char* )Standard::Allocate (aFileLen);
116 fseek (aFileHandle, 0, SEEK_SET);
117 size_t aCountRead = fread (aBuffer, 1, aFileLen, aFileHandle);
119 fclose (aFileHandle);
121 uint32_t aCpuMask = 0;
122 const char* anEnd = aBuffer + aFileLen;
123 for (const char* aCharIter = aBuffer; aCharIter < anEnd && *aCharIter != '\n';)
125 const char* aChunkEnd = (const char* )::memchr (aCharIter, ',', anEnd - aCharIter);
126 if (aChunkEnd == NULL)
132 int anIndexLower = 0;
133 aCharIter = parseNumber (anIndexLower, aCharIter, aChunkEnd);
134 if (aCharIter == NULL)
136 Standard::Free (aBuffer);
140 // if we're not at the end of the item, expect a dash and and integer; extract end value.
141 int anIndexUpper = anIndexLower;
142 if (aCharIter < aChunkEnd && *aCharIter == '-')
144 aCharIter = parseNumber (anIndexUpper, aCharIter + 1, aChunkEnd);
145 if (aCharIter == NULL)
147 Standard::Free (aBuffer);
153 for (int aCpuIndex = anIndexLower; aCpuIndex <= anIndexUpper; ++aCpuIndex)
155 if ((unsigned int )aCpuIndex < 32)
157 aCpuMask |= (uint32_t )(1U << aCpuIndex);
161 aCharIter = aChunkEnd;
162 if (aCharIter < anEnd)
168 Standard::Free (aBuffer);
175 //=======================================================================
176 //function : NbLogicalProcessors
177 //purpose : Returns number of logical proccessors.
178 //=======================================================================
179 Standard_Integer OSD_Parallel::NbLogicalProcessors()
181 static Standard_Integer aNumLogicalProcessors = 0;
182 if ( aNumLogicalProcessors != 0 )
184 return aNumLogicalProcessors;
187 // GetSystemInfo() will return the number of processors in a data field in a SYSTEM_INFO structure.
188 SYSTEM_INFO aSysInfo;
192 typedef BOOL (WINAPI *LPFN_GSI)(LPSYSTEM_INFO );
194 HMODULE aKern32 = GetModuleHandleW(L"kernel32");
195 LPFN_GSI aFuncSysInfo = (LPFN_GSI )GetProcAddress(aKern32, "GetNativeSystemInfo");
197 // So, they suggest 32-bit apps should call this instead of the other in WOW64
198 if ( aFuncSysInfo != NULL )
200 aFuncSysInfo(&aSysInfo);
204 GetSystemInfo(&aSysInfo);
209 GetSystemInfo(&aSysInfo);
212 GetNativeSystemInfo(&aSysInfo);
214 aNumLogicalProcessors = aSysInfo.dwNumberOfProcessors;
217 #if defined(__ANDROID__)
218 uint32_t aCpuMaskPresent = readCpuMask ("/sys/devices/system/cpu/present");
219 uint32_t aCpuMaskPossible = readCpuMask ("/sys/devices/system/cpu/possible");
220 aCpuMaskPresent &= aCpuMaskPossible;
221 aNumLogicalProcessors = __builtin_popcount (aCpuMaskPresent);
222 if (aNumLogicalProcessors >= 1)
224 return aNumLogicalProcessors;
228 // These are the choices. We'll check number of processors online.
229 // _SC_NPROCESSORS_CONF Number of processors configured
230 // _SC_NPROCESSORS_MAX Max number of processors supported by platform
231 // _SC_NPROCESSORS_ONLN Number of processors online
232 aNumLogicalProcessors = (Standard_Integer)sysconf(_SC_NPROCESSORS_ONLN);
234 return aNumLogicalProcessors;