diff --git a/src/OSD/OSD_Parallel.cxx b/src/OSD/OSD_Parallel.cxx index 28de4c66cd..2a6cbf222b 100644 --- a/src/OSD/OSD_Parallel.cxx +++ b/src/OSD/OSD_Parallel.cxx @@ -17,22 +17,23 @@ #include #ifdef _WIN32 - #include - #include + #include + #include #else - #include + #include - #ifdef __sun - #include - #include - #else - #include - #endif + #ifdef __sun + #include + #include + #else + #include + #endif #endif -#if defined(_WIN32) && !defined(OCCT_UWP) namespace { - // for a 64-bit app running under 64-bit Windows, this is FALSE + +#if defined(_WIN32) && !defined(OCCT_UWP) + //! For a 64-bit app running under 64-bit Windows, this is FALSE. static bool isWow64() { typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE , PBOOL); @@ -46,9 +47,131 @@ namespace { aFunIsWow64(GetCurrentProcess(), &bIsWow64) && bIsWow64 != FALSE; } -} + +#elif defined(__ANDROID__) + + //! Simple number parser. + static const char* parseNumber (int& theResult, + const char* theInput, + const char* theLimit, + const int theBase = 10) + { + const char* aCharIter = theInput; + int aValue = 0; + while (aCharIter < theLimit) + { + int aDigit = (*aCharIter - '0'); + if ((unsigned int )aDigit >= 10U) + { + aDigit = (*aCharIter - 'a'); + if ((unsigned int )aDigit >= 6U) + { + aDigit = (*aCharIter - 'A'); + } + if ((unsigned int )aDigit >= 6U) + { + break; + } + aDigit += 10; + } + if (aDigit >= theBase) + { + break; + } + aValue = aValue * theBase + aDigit; + ++aCharIter; + } + if (aCharIter == theInput) + { + return NULL; + } + + theResult = aValue; + return aCharIter; + } + + //! Read CPUs mask from sysfs. + static uint32_t readCpuMask (const char* thePath) + { + FILE* aFileHandle = fopen (thePath, "rb"); + if (aFileHandle == NULL) + { + return 0; + } + + fseek (aFileHandle, 0, SEEK_END); + long aFileLen = ftell (aFileHandle); + if (aFileLen <= 0L) + { + fclose (aFileHandle); + return 0; + } + + char* aBuffer = (char* )Standard::Allocate (aFileLen); + if (aBuffer == NULL) + { + return 0; + } + + fseek (aFileHandle, 0, SEEK_SET); + size_t aCountRead = fread (aBuffer, 1, aFileLen, aFileHandle); + (void )aCountRead; + fclose (aFileHandle); + + uint32_t aCpuMask = 0; + const char* anEnd = aBuffer + aFileLen; + for (const char* aCharIter = aBuffer; aCharIter < anEnd && *aCharIter != '\n';) + { + const char* aChunkEnd = (const char* )::memchr (aCharIter, ',', anEnd - aCharIter); + if (aChunkEnd == NULL) + { + aChunkEnd = anEnd; + } + + // get first value + int anIndexLower = 0; + aCharIter = parseNumber (anIndexLower, aCharIter, aChunkEnd); + if (aCharIter == NULL) + { + Standard::Free (aBuffer); + return aCpuMask; + } + + // if we're not at the end of the item, expect a dash and and integer; extract end value. + int anIndexUpper = anIndexLower; + if (aCharIter < aChunkEnd && *aCharIter == '-') + { + aCharIter = parseNumber (anIndexUpper, aCharIter + 1, aChunkEnd); + if (aCharIter == NULL) + { + Standard::Free (aBuffer); + return aCpuMask; + } + } + + // set bits CPU list + for (int aCpuIndex = anIndexLower; aCpuIndex <= anIndexUpper; ++aCpuIndex) + { + if ((unsigned int )aCpuIndex < 32) + { + aCpuMask |= (uint32_t )(1U << aCpuIndex); + } + } + + aCharIter = aChunkEnd; + if (aCharIter < anEnd) + { + ++aCharIter; + } + } + + Standard::Free (aBuffer); + return aCpuMask; + } #endif +} + //======================================================================= //function : NbLogicalProcessors //purpose : Returns number of logical proccessors. @@ -90,6 +213,18 @@ Standard_Integer OSD_Parallel::NbLogicalProcessors() #endif aNumLogicalProcessors = aSysInfo.dwNumberOfProcessors; #else + +#if defined(__ANDROID__) + uint32_t aCpuMaskPresent = readCpuMask ("/sys/devices/system/cpu/present"); + uint32_t aCpuMaskPossible = readCpuMask ("/sys/devices/system/cpu/possible"); + aCpuMaskPresent &= aCpuMaskPossible; + aNumLogicalProcessors = __builtin_popcount (aCpuMaskPresent); + if (aNumLogicalProcessors >= 1) + { + return aNumLogicalProcessors; + } +#endif + // These are the choices. We'll check number of processors online. // _SC_NPROCESSORS_CONF Number of processors configured // _SC_NPROCESSORS_MAX Max number of processors supported by platform