win32/deThreadLocalWin32.c
)
-elseif (DE_OS_IS_UNIX OR DE_OS_IS_ANDROID OR DE_OS_IS_SYMBIAN)
- add_definitions(-D_XOPEN_SOURCE=600)
+elseif (DE_OS_IS_UNIX OR DE_OS_IS_ANDROID)
+ if (DE_OS_IS_UNIX)
+ add_definitions(-D_GNU_SOURCE)
+ set(DETHREAD_LIBS ${DETHREAD_LIBS} pthread)
+ else ()
+ add_definitions(-D_XOPEN_SOURCE=600)
+ endif ()
+
set(DETHREAD_SRCS
${DETHREAD_SRCS}
unix/deMutexUnix.c
unix/deThreadLocalUnix.c
)
- if (DE_OS_IS_UNIX)
- set(DETHREAD_LIBS ${DETHREAD_LIBS} pthread)
- elseif (DE_OS_IS_SYMBIAN)
- find_file(PTHREAD_LIB libpthread.dso PATHS ${SYMBIAN_LIB_DIR} NO_CMAKE_FIND_ROOT_PATH)
- set(DETHREAD_LIBS ${DETHREAD_LIBS} ${PTHREAD_LIB})
- endif ()
-
elseif (DE_OS_IS_OSX OR DE_OS_IS_IOS)
add_definitions(-D_XOPEN_SOURCE=600)
# \note OS X doesn't support unnamed semaphores.
deThreadPriority priority;
} deThreadAttributes;
-void deSleep (deUint32 milliseconds);
-void deYield (void);
+void deSleep (deUint32 milliseconds);
+void deYield (void);
-deThread deThread_create (deThreadFunc func, void* arg, const deThreadAttributes* attributes);
-deBool deThread_join (deThread thread);
-void deThread_destroy (deThread thread);
+deThread deThread_create (deThreadFunc func, void* arg, const deThreadAttributes* attributes);
+deBool deThread_join (deThread thread);
+void deThread_destroy (deThread thread);
+
+deUint32 deGetNumTotalPhysicalCores (void);
+deUint32 deGetNumTotalLogicalCores (void);
+deUint32 deGetNumAvailableLogicalCores (void);
DE_END_EXTERN_C
#include "deMemory.h"
#if !defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE < 500)
-# error You are using too old posix API!
+# error "You are using too old posix API!"
#endif
#include <unistd.h>
sched_yield();
}
+#if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
+
+deUint32 deGetNumAvailableLogicalCores (void)
+{
+ cpu_set_t cpuSet;
+
+ CPU_ZERO(&cpuSet);
+
+ if (sched_getaffinity(0, sizeof(cpuSet), &cpuSet) != 0)
+ return 1;
+
+ return (deUint32)(CPU_COUNT(&cpuSet));
+}
+
+#else
+
+deUint32 deGetNumAvailableLogicalCores (void)
+{
+ return (deUint32)sysconf(_SC_NPROCESSORS_ONLN);
+}
+
+#endif
+
+deUint32 deGetNumTotalLogicalCores (void)
+{
+ return (deUint32)sysconf(_SC_NPROCESSORS_CONF);
+}
+
+deUint32 deGetNumTotalPhysicalCores (void)
+{
+ /* \todo [2015-04-09 pyry] Parse /proc/cpuinfo perhaps? */
+ return deGetNumTotalLogicalCores();
+}
+
#endif /* DE_OS */
#if (DE_OS == DE_OS_WIN32 || DE_OS == DE_OS_WINCE)
#include "deMemory.h"
+#include "deInt32.h"
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
SwitchToThread();
}
+static SYSTEM_LOGICAL_PROCESSOR_INFORMATION* getWin32ProcessorInfo (deUint32* numBytes)
+{
+ deUint32 curSize = (deUint32)sizeof(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)*8;
+ SYSTEM_LOGICAL_PROCESSOR_INFORMATION* info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION*)deMalloc(curSize);
+
+ for (;;)
+ {
+ DWORD inOutLen = curSize;
+ DWORD err;
+
+ if (GetLogicalProcessorInformation(info, &inOutLen))
+ {
+ *numBytes = inOutLen;
+ return info;
+ }
+ else
+ {
+ err = GetLastError();
+
+ if (err == ERROR_INSUFFICIENT_BUFFER)
+ {
+ curSize <<= 1;
+ info = deRealloc(info, curSize);
+ }
+ else
+ {
+ deFree(info);
+ return DE_NULL;
+ }
+ }
+ }
+}
+
+typedef struct ProcessorInfo_s
+{
+ deUint32 numPhysicalCores;
+ deUint32 numLogicalCores;
+} ProcessorInfo;
+
+void parseWin32ProcessorInfo (ProcessorInfo* dst, const SYSTEM_LOGICAL_PROCESSOR_INFORMATION* src, deUint32 numBytes)
+{
+ const SYSTEM_LOGICAL_PROCESSOR_INFORMATION* cur = src;
+
+ deMemset(dst, 0, sizeof(ProcessorInfo));
+
+ while (((const deUint8*)cur - (const deUint8*)src) + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= numBytes)
+ {
+ if (cur->Relationship == RelationProcessorCore)
+ {
+ dst->numPhysicalCores += 1;
+#if (DE_PTR_SIZE == 8)
+ dst->numLogicalCores += dePop64(cur->ProcessorMask);
+#else
+ dst->numLogicalCores += dePop32(cur->ProcessorMask);
+#endif
+ }
+
+ cur++;
+ }
+}
+
+deBool getProcessorInfo (ProcessorInfo* info)
+{
+ deUint32 numBytes = 0;
+ SYSTEM_LOGICAL_PROCESSOR_INFORMATION* rawInfo = getWin32ProcessorInfo(&numBytes);
+
+ if (!numBytes)
+ return DE_FALSE;
+
+ parseWin32ProcessorInfo(info, rawInfo, numBytes);
+ deFree(rawInfo);
+
+ return DE_TRUE;
+}
+
+deUint32 deGetNumTotalPhysicalCores (void)
+{
+ ProcessorInfo info;
+
+ if (!getProcessorInfo(&info))
+ return 1u;
+
+ return info.numPhysicalCores;
+}
+
+deUint32 deGetNumTotalLogicalCores (void)
+{
+ ProcessorInfo info;
+
+ if (!getProcessorInfo(&info))
+ return 1u;
+
+ return info.numLogicalCores;
+}
+
+deUint32 deGetNumAvailableLogicalCores (void)
+{
+ return deGetNumTotalLogicalCores();
+}
+
#endif /* DE_OS */
*//*--------------------------------------------------------------------*/
#include "ditDelibsTests.hpp"
+#include "tcuTestLog.hpp"
// depool
#include "dePoolArray.h"
// dethread
#include "deThreadTest.h"
+#include "deThread.h"
// deutil
#include "deTimerTest.h"
namespace dit
{
+using tcu::TestLog;
+
class DepoolTests : public tcu::TestCaseGroup
{
public:
}
};
+extern "C"
+{
+typedef deUint32 (*GetUint32Func) (void);
+}
+
+class GetUint32Case : public tcu::TestCase
+{
+public:
+ GetUint32Case (tcu::TestContext& testCtx, const char* name, const char* description, GetUint32Func func)
+ : tcu::TestCase (testCtx, name, description)
+ , m_func (func)
+ {
+ }
+
+ IterateResult iterate (void)
+ {
+ m_testCtx.getLog() << TestLog::Message << getDescription() << " returned " << m_func() << TestLog::EndMessage;
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ return STOP;
+ }
+
+private:
+ GetUint32Func m_func;
+};
+
class DethreadTests : public tcu::TestCaseGroup
{
public:
void init (void)
{
- addChild(new SelfCheckCase(m_testCtx, "thread", "deThread_selfTest()", deThread_selfTest));
- addChild(new SelfCheckCase(m_testCtx, "mutex", "deMutex_selfTest()", deMutex_selfTest));
- addChild(new SelfCheckCase(m_testCtx, "semaphore", "deSemaphore_selfTest()", deSemaphore_selfTest));
- addChild(new SelfCheckCase(m_testCtx, "atomic", "deAtomic_selfTest()", deAtomic_selfTest));
- addChild(new SelfCheckCase(m_testCtx, "singleton", "deSingleton_selfTest()", deSingleton_selfTest));
+ addChild(new SelfCheckCase(m_testCtx, "thread", "deThread_selfTest()", deThread_selfTest));
+ addChild(new SelfCheckCase(m_testCtx, "mutex", "deMutex_selfTest()", deMutex_selfTest));
+ addChild(new SelfCheckCase(m_testCtx, "semaphore", "deSemaphore_selfTest()", deSemaphore_selfTest));
+ addChild(new SelfCheckCase(m_testCtx, "atomic", "deAtomic_selfTest()", deAtomic_selfTest));
+ addChild(new SelfCheckCase(m_testCtx, "singleton", "deSingleton_selfTest()", deSingleton_selfTest));
+ addChild(new GetUint32Case(m_testCtx, "total_physical_cores", "deGetNumTotalPhysicalCores()", deGetNumTotalPhysicalCores));
+ addChild(new GetUint32Case(m_testCtx, "total_logical_cores", "deGetNumTotalLogicalCores()", deGetNumTotalLogicalCores));
+ addChild(new GetUint32Case(m_testCtx, "available_logical_cores", "deGetNumAvailableLogicalCores()", deGetNumAvailableLogicalCores));
}
};