0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / OSD / OSD_Parallel.cxx
CommitLineData
c7b59798 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
5//
6// This file is part of Open CASCADE Technology software library.
7//
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.
13//
14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
16
17#include <OSD_Parallel.hxx>
18
19#ifdef _WIN32
4897e58d 20 #include <windows.h>
21 #include <process.h>
c7b59798 22#else
4897e58d 23 #include <sys/types.h>
00af0ebb 24 #include <unistd.h>
4897e58d 25
26 #ifdef __sun
27 #include <sys/processor.h>
28 #include <sys/procset.h>
29 #else
30 #include <sched.h>
31 #endif
c7b59798 32#endif
33
f4a7308f 34#include <Standard_WarningDisableFunctionCast.hxx>
35
c7b59798 36namespace {
4897e58d 37
38#if defined(_WIN32) && !defined(OCCT_UWP)
39 //! For a 64-bit app running under 64-bit Windows, this is FALSE.
c7b59798 40 static bool isWow64()
41 {
42 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE , PBOOL);
43 BOOL bIsWow64 = FALSE;
742cc8b0 44
c7b59798 45 HMODULE aKern32Module = GetModuleHandleW(L"kernel32");
46 LPFN_ISWOW64PROCESS aFunIsWow64 = (aKern32Module == NULL) ? (LPFN_ISWOW64PROCESS )NULL
47 : (LPFN_ISWOW64PROCESS)GetProcAddress(aKern32Module, "IsWow64Process");
48
49 return aFunIsWow64 != NULL &&
50 aFunIsWow64(GetCurrentProcess(), &bIsWow64) &&
51 bIsWow64 != FALSE;
52 }
4897e58d 53
54#elif defined(__ANDROID__)
55
56 //! Simple number parser.
57 static const char* parseNumber (int& theResult,
58 const char* theInput,
59 const char* theLimit,
60 const int theBase = 10)
61 {
62 const char* aCharIter = theInput;
63 int aValue = 0;
64 while (aCharIter < theLimit)
65 {
66 int aDigit = (*aCharIter - '0');
67 if ((unsigned int )aDigit >= 10U)
68 {
69 aDigit = (*aCharIter - 'a');
70 if ((unsigned int )aDigit >= 6U)
71 {
72 aDigit = (*aCharIter - 'A');
73 }
74 if ((unsigned int )aDigit >= 6U)
75 {
76 break;
77 }
78 aDigit += 10;
79 }
80 if (aDigit >= theBase)
81 {
82 break;
83 }
84 aValue = aValue * theBase + aDigit;
85 ++aCharIter;
86 }
87 if (aCharIter == theInput)
88 {
89 return NULL;
90 }
91
92 theResult = aValue;
93 return aCharIter;
94 }
95
96 //! Read CPUs mask from sysfs.
97 static uint32_t readCpuMask (const char* thePath)
98 {
99 FILE* aFileHandle = fopen (thePath, "rb");
100 if (aFileHandle == NULL)
101 {
102 return 0;
103 }
104
105 fseek (aFileHandle, 0, SEEK_END);
106 long aFileLen = ftell (aFileHandle);
107 if (aFileLen <= 0L)
108 {
109 fclose (aFileHandle);
110 return 0;
111 }
112
113 char* aBuffer = (char* )Standard::Allocate (aFileLen);
114 if (aBuffer == NULL)
115 {
116 return 0;
117 }
118
119 fseek (aFileHandle, 0, SEEK_SET);
120 size_t aCountRead = fread (aBuffer, 1, aFileLen, aFileHandle);
121 (void )aCountRead;
122 fclose (aFileHandle);
123
124 uint32_t aCpuMask = 0;
125 const char* anEnd = aBuffer + aFileLen;
126 for (const char* aCharIter = aBuffer; aCharIter < anEnd && *aCharIter != '\n';)
127 {
128 const char* aChunkEnd = (const char* )::memchr (aCharIter, ',', anEnd - aCharIter);
129 if (aChunkEnd == NULL)
130 {
131 aChunkEnd = anEnd;
132 }
133
134 // get first value
135 int anIndexLower = 0;
136 aCharIter = parseNumber (anIndexLower, aCharIter, aChunkEnd);
137 if (aCharIter == NULL)
138 {
139 Standard::Free (aBuffer);
140 return aCpuMask;
141 }
142
23fe70ec 143 // if we're not at the end of the item, expect a dash and integer; extract end value.
4897e58d 144 int anIndexUpper = anIndexLower;
145 if (aCharIter < aChunkEnd && *aCharIter == '-')
146 {
147 aCharIter = parseNumber (anIndexUpper, aCharIter + 1, aChunkEnd);
148 if (aCharIter == NULL)
149 {
150 Standard::Free (aBuffer);
151 return aCpuMask;
152 }
153 }
154
155 // set bits CPU list
156 for (int aCpuIndex = anIndexLower; aCpuIndex <= anIndexUpper; ++aCpuIndex)
157 {
158 if ((unsigned int )aCpuIndex < 32)
159 {
160 aCpuMask |= (uint32_t )(1U << aCpuIndex);
161 }
162 }
163
164 aCharIter = aChunkEnd;
165 if (aCharIter < anEnd)
166 {
167 ++aCharIter;
168 }
169 }
170
171 Standard::Free (aBuffer);
172 return aCpuMask;
173 }
c7b59798 174#endif
175
fc867b96 176 static Standard_Boolean OSD_Parallel_ToUseOcctThreads =
177 #ifdef HAVE_TBB
178 Standard_False;
179 #else
180 Standard_True;
181 #endif
182}
183
184//=======================================================================
185//function : ToUseOcctThreads
186//purpose :
187//=======================================================================
188Standard_Boolean OSD_Parallel::ToUseOcctThreads()
189{
190 return OSD_Parallel_ToUseOcctThreads;
191}
192
193//=======================================================================
194//function : SetUseOcctThreads
195//purpose :
196//=======================================================================
197void OSD_Parallel::SetUseOcctThreads (Standard_Boolean theToUseOcct)
198{
199#ifdef HAVE_TBB
200 OSD_Parallel_ToUseOcctThreads = theToUseOcct;
201#else
202 (void )theToUseOcct;
203#endif
4897e58d 204}
205
c7b59798 206//=======================================================================
207//function : NbLogicalProcessors
5e6e5914 208//purpose : Returns number of logical processors.
c7b59798 209//=======================================================================
210Standard_Integer OSD_Parallel::NbLogicalProcessors()
211{
212 static Standard_Integer aNumLogicalProcessors = 0;
213 if ( aNumLogicalProcessors != 0 )
214 {
215 return aNumLogicalProcessors;
216 }
217#ifdef _WIN32
218 // GetSystemInfo() will return the number of processors in a data field in a SYSTEM_INFO structure.
219 SYSTEM_INFO aSysInfo;
742cc8b0 220#ifndef OCCT_UWP
c7b59798 221 if ( isWow64() )
222 {
223 typedef BOOL (WINAPI *LPFN_GSI)(LPSYSTEM_INFO );
742cc8b0 224
c7b59798 225 HMODULE aKern32 = GetModuleHandleW(L"kernel32");
226 LPFN_GSI aFuncSysInfo = (LPFN_GSI )GetProcAddress(aKern32, "GetNativeSystemInfo");
742cc8b0 227
c7b59798 228 // So, they suggest 32-bit apps should call this instead of the other in WOW64
229 if ( aFuncSysInfo != NULL )
230 {
231 aFuncSysInfo(&aSysInfo);
232 }
233 else
234 {
235 GetSystemInfo(&aSysInfo);
236 }
237 }
238 else
239 {
240 GetSystemInfo(&aSysInfo);
241 }
742cc8b0 242#else
243 GetNativeSystemInfo(&aSysInfo);
244#endif
c7b59798 245 aNumLogicalProcessors = aSysInfo.dwNumberOfProcessors;
246#else
4897e58d 247
248#if defined(__ANDROID__)
249 uint32_t aCpuMaskPresent = readCpuMask ("/sys/devices/system/cpu/present");
250 uint32_t aCpuMaskPossible = readCpuMask ("/sys/devices/system/cpu/possible");
251 aCpuMaskPresent &= aCpuMaskPossible;
252 aNumLogicalProcessors = __builtin_popcount (aCpuMaskPresent);
253 if (aNumLogicalProcessors >= 1)
254 {
255 return aNumLogicalProcessors;
256 }
257#endif
258
c7b59798 259 // These are the choices. We'll check number of processors online.
260 // _SC_NPROCESSORS_CONF Number of processors configured
261 // _SC_NPROCESSORS_MAX Max number of processors supported by platform
262 // _SC_NPROCESSORS_ONLN Number of processors online
263 aNumLogicalProcessors = (Standard_Integer)sysconf(_SC_NPROCESSORS_ONLN);
264#endif
265 return aNumLogicalProcessors;
266}