1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0027854: Foundation Classes - OSD_Parallel::NbLogicalProcessors() should handle Android specifically

Read CPU info from sysfs.
This commit is contained in:
kgv 2016-09-08 22:54:54 +03:00 committed by bugmaster
parent 70ca46fecc
commit 4897e58dcd

View File

@ -17,22 +17,23 @@
#include <OSD_Parallel.hxx>
#ifdef _WIN32
#include <windows.h>
#include <process.h>
#include <windows.h>
#include <process.h>
#else
#include <sys/types.h>
#include <sys/types.h>
#ifdef __sun
#include <sys/processor.h>
#include <sys/procset.h>
#else
#include <sched.h>
#endif
#ifdef __sun
#include <sys/processor.h>
#include <sys/procset.h>
#else
#include <sched.h>
#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