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)
# For SetAffinity
if(UNIX)
if(UNIX AND NOT APPLE)
INCLUDE (CheckFunctionExists)
INCLUDE (CheckCXXSourceCompiles)
CHECK_FUNCTION_EXISTS(pthread_setaffinity_np HAVE_PTHREAD_SETAFFINITY_NP)
@ -143,7 +143,7 @@ if(UNIX)
endif(HAVE_THREE_PARAM_SCHED_SETAFFINITY)
endif(HAVE_PTHREAD_SETAFFINITY_NP)
endif(UNIX)
endif(UNIX AND NOT APPLE)
add_library( "${LIBNAME}" ${LIB_MODE} ${SRCS})
add_library( "${POCO_LIBNAME}" ALIAS "${LIBNAME}")

View File

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

View File

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

View File

@ -19,12 +19,14 @@
#include "Poco/Event.h"
#include "Poco/Timestamp.h"
#include "Poco/Timespan.h"
#include "Poco/Environment.h"
//#include <iostream>
#if defined(__sun) && defined(__SVR4) && !defined(__EXTENSIONS__)
#define __EXTENSIONS__
#endif
#include <climits>
#include <vector>
#include <sstream>
using Poco::Thread;
using Poco::Runnable;
@ -449,6 +451,67 @@ void ThreadTest::testSleep()
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()
{
@ -478,6 +541,7 @@ CppUnit::Test* ThreadTest::suite()
CppUnit_addTest(pSuite, ThreadTest, testThreadFunctor);
CppUnit_addTest(pSuite, ThreadTest, testThreadStackSize);
CppUnit_addTest(pSuite, ThreadTest, testSleep);
CppUnit_addTest(pSuite, ThreadTest, testAffinity);
return pSuite;
}

View File

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