add test for thread affinity and fix some problems

This commit is contained in:
ale_bychuk
2015-03-07 10:55:23 +03:00
parent 888abad26c
commit 662fbc861a
5 changed files with 84 additions and 10 deletions

View File

@@ -108,7 +108,7 @@ endif (${CMAKE_CXX_COMPILER_ID} MATCHES "SunPro")
add_definitions( -DPCRE_STATIC) add_definitions( -DPCRE_STATIC)
# For SetAffinity # For SetAffinity
if(UNIX) if(UNIX AND NOT APPLE)
INCLUDE (CheckFunctionExists) INCLUDE (CheckFunctionExists)
INCLUDE (CheckCXXSourceCompiles) INCLUDE (CheckCXXSourceCompiles)
CHECK_FUNCTION_EXISTS(pthread_setaffinity_np HAVE_PTHREAD_SETAFFINITY_NP) CHECK_FUNCTION_EXISTS(pthread_setaffinity_np HAVE_PTHREAD_SETAFFINITY_NP)
@@ -143,7 +143,7 @@ if(UNIX)
endif(HAVE_THREE_PARAM_SCHED_SETAFFINITY) endif(HAVE_THREE_PARAM_SCHED_SETAFFINITY)
endif(HAVE_PTHREAD_SETAFFINITY_NP) endif(HAVE_PTHREAD_SETAFFINITY_NP)
endif(UNIX) endif(UNIX AND NOT APPLE)
add_library( "${LIBNAME}" ${LIB_MODE} ${SRCS}) add_library( "${LIBNAME}" ${LIB_MODE} ${SRCS})
add_library( "${POCO_LIBNAME}" ALIAS "${LIBNAME}") add_library( "${POCO_LIBNAME}" ALIAS "${LIBNAME}")

View File

@@ -135,11 +135,14 @@ public:
/// Typically, the real stack size is rounded up to the nearest /// Typically, the real stack size is rounded up to the nearest
/// page size multiple. /// page size multiple.
void setAffinity(unsigned int cpu); void setAffinity(unsigned int cpu);
/// Limit specified thread to run only on the processors "cpu" /// Limit specified thread to run only on the processors "cpu"
/// cpu - processor (core) number /// cpu - processor (core) number
/// Method would Throw SystemException if affinity did not setted /// Method would Throw SystemException if affinity did not setted
unsigned getAffinity() const;
/// Returns using cpu (core) number
int getStackSize() const; int getStackSize() const;
/// Returns the thread's stack size in bytes. /// Returns the thread's stack size in bytes.
/// If the default stack size is used, 0 is returned. /// If the default stack size is used, 0 is returned.
@@ -355,10 +358,16 @@ inline void Thread::setStackSize(int size)
setStackSizeImpl(size); setStackSizeImpl(size);
} }
inline void Thread::setAffinity(unsigned int cpu) { inline void Thread::setAffinity(unsigned int cpu)
{
setAffinityImpl(cpu); setAffinityImpl(cpu);
} }
inline unsigned Thread::getAffinity() const
{
return getAffinityImpl();
}
inline int Thread::getStackSize() const inline int Thread::getStackSize() const
{ {
return getStackSizeImpl(); return getStackSizeImpl();

View File

@@ -199,7 +199,7 @@ void ThreadImpl::setAffinityImpl(unsigned cpu)
throw SystemException("Failed to set affinity"); throw SystemException("Failed to set affinity");
#endif #endif
#else #else
poco_bugcheck_msg("Thread affinity not supported on this system"); throw Poco::NotImplementedException("Thread affinity not supported on this system");
#endif #endif
#endif // defined unix & !defined mac os x #endif // defined unix & !defined mac os x
@@ -229,10 +229,10 @@ unsigned cpuCount = Environment::processorCount();
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
#ifdef HAVE_THREE_PARAM_SCHED_SETAFFINITY #ifdef HAVE_THREE_PARAM_SCHED_SETAFFINITY
if (pthread_getaffinity_np(_pData->thread, sizeof(cpuset), &cpuset) != 0) if (pthread_getaffinity_np(_pData->thread, sizeof(cpuset), &cpuset) != 0)
throw SystemException("Failed to get affinity"); throw SystemException("Failed to get affinity", errno);
#else #else
if (pthread_getaffinity_np(_pData->thread, &cpuset) != 0) if (pthread_getaffinity_np(_pData->thread, &cpuset) != 0)
throw SystemException("Failed to get affinity"); throw SystemException("Failed to get affinity", errno);
#endif #endif
for (unsigned i = 0; i < cpuCount; i++) { for (unsigned i = 0; i < cpuCount; i++) {
if (CPU_ISSET(i, &cpuset)) { if (CPU_ISSET(i, &cpuset)) {
@@ -256,9 +256,9 @@ unsigned cpuCount = Environment::processorCount();
&count, &count,
&get_default); &get_default);
if (ret != KERN_SUCCESS) { if (ret != KERN_SUCCESS) {
throw SystemException("Failed to get affinity"); throw SystemException("Failed to get affinity", errno);
} }
cpuSet = policy.affinity_tag - 1; cpuSet = policy.affinity_tag;
if (cpuSet >= cpuCount) if (cpuSet >= cpuCount)
cpuSet = 0; cpuSet = 0;

View File

@@ -19,12 +19,14 @@
#include "Poco/Event.h" #include "Poco/Event.h"
#include "Poco/Timestamp.h" #include "Poco/Timestamp.h"
#include "Poco/Timespan.h" #include "Poco/Timespan.h"
#include "Poco/Environment.h"
//#include <iostream> //#include <iostream>
#if defined(__sun) && defined(__SVR4) && !defined(__EXTENSIONS__) #if defined(__sun) && defined(__SVR4) && !defined(__EXTENSIONS__)
#define __EXTENSIONS__ #define __EXTENSIONS__
#endif #endif
#include <climits> #include <climits>
#include <vector>
#include <sstream>
using Poco::Thread; using Poco::Thread;
using Poco::Runnable; using Poco::Runnable;
@@ -449,6 +451,67 @@ void ThreadTest::testSleep()
assert (elapsed.totalMilliseconds() >= 190 && elapsed.totalMilliseconds() < 250); assert (elapsed.totalMilliseconds() >= 190 && elapsed.totalMilliseconds() < 250);
} }
void ThreadTest::testAffinity()
{
std::stringstream ss;
unsigned cpuCount = Poco::Environment::processorCount();
unsigned usedCpu = 0;
bool notImplemented = false;
std::vector<Thread *> threadList;
Thread *thread = NULL;
std::vector<MyRunnable *> runnableList;
MyRunnable *runbl = NULL;
for (unsigned i = 0; i < cpuCount; i++)
{
ss.str("");
ss << "Thread" << i;
thread = new Thread(ss.str());
threadList.push_back(thread);
runbl = new MyRunnable();
runnableList.push_back(runbl);
}
for (int i = 0; i < cpuCount; i++)
{
assert (!threadList[i]->isRunning());
}
for (int i = 0; i < cpuCount; i++)
{
threadList[i]->start(*runnableList[i]);
try
{
threadList[i]->setAffinity(i);
}
catch (Poco::NotImplementedException &niex)
{
notImplemented = true;
}
Thread::sleep(100);
try
{
usedCpu = threadList[i]->getAffinity();
}
catch (Poco::NotImplementedException &niex)
{
notImplemented = true;
}
if (!notImplemented)
{
assert (usedCpu == i);
}
}
for (int i = 0; i < cpuCount; i++)
{
runnableList[i]->notify();
threadList[i]->join();
delete runnableList[i];
delete threadList[i];
}
}
void ThreadTest::setUp() void ThreadTest::setUp()
{ {
@@ -478,6 +541,7 @@ CppUnit::Test* ThreadTest::suite()
CppUnit_addTest(pSuite, ThreadTest, testThreadFunctor); CppUnit_addTest(pSuite, ThreadTest, testThreadFunctor);
CppUnit_addTest(pSuite, ThreadTest, testThreadStackSize); CppUnit_addTest(pSuite, ThreadTest, testThreadStackSize);
CppUnit_addTest(pSuite, ThreadTest, testSleep); CppUnit_addTest(pSuite, ThreadTest, testSleep);
CppUnit_addTest(pSuite, ThreadTest, testAffinity);
return pSuite; return pSuite;
} }

View File

@@ -40,6 +40,7 @@ public:
void testThreadFunctor(); void testThreadFunctor();
void testThreadStackSize(); void testThreadStackSize();
void testSleep(); void testSleep();
void testAffinity();
void setUp(); void setUp();
void tearDown(); void tearDown();