diff --git a/Foundation/include/Poco/Thread.h b/Foundation/include/Poco/Thread.h index 606efd826..82836408f 100644 --- a/Foundation/include/Poco/Thread.h +++ b/Foundation/include/Poco/Thread.h @@ -110,6 +110,23 @@ public: Priority getPriority() const; /// Returns the thread's priority. + void setOSPriority(int prio); + /// Sets the thread's priority, using an operating system specific + /// priority value. Use getMinOSPriority() and getMaxOSPriority() to + /// obtain mininum and maximum priority values. + + int getOSPriority() const; + /// Returns the thread's priority, expressed as an operating system + /// specific priority value. + + static int getMinOSPriority(); + /// Returns the mininum operating system-specific priority value, + /// which can be passed to setOSPriority(). + + static int getMaxOSPriority(); + /// Returns the maximum operating system-specific priority value, + /// which can be passed to setOSPriority(). + void setStackSize(std::size_t size); /// Sets the thread's stack size in bytes. /// Setting the stack size to 0 will use the default stack size. @@ -231,6 +248,30 @@ inline Thread* Thread::current() } +inline void Thread::setOSPriority(int prio) +{ + setOSPriorityImpl(prio); +} + + +inline int Thread::getOSPriority() const +{ + return getOSPriorityImpl(); +} + + +inline int Thread::getMinOSPriority() +{ + return ThreadImpl::getMinOSPriorityImpl(); +} + + +inline int Thread::getMaxOSPriority() +{ + return ThreadImpl::getMaxOSPriorityImpl(); +} + + inline void Thread::setStackSize(std::size_t size) { setStackSizeImpl(size); diff --git a/Foundation/include/Poco/Thread_POSIX.h b/Foundation/include/Poco/Thread_POSIX.h index bdf0617fb..d72bdc1fd 100644 --- a/Foundation/include/Poco/Thread_POSIX.h +++ b/Foundation/include/Poco/Thread_POSIX.h @@ -85,6 +85,10 @@ public: void setPriorityImpl(int prio); int getPriorityImpl() const; + void setOSPriorityImpl(int prio); + int getOSPriorityImpl() const; + static int getMinOSPriorityImpl(); + static int getMaxOSPriorityImpl(); void setStackSizeImpl(std::size_t size); std::size_t getStackSizeImpl() const; void startImpl(Runnable& target); @@ -101,6 +105,7 @@ protected: static void* runnableEntry(void* pThread); static void* functionEntry(void* pThread); static int mapPrio(int prio); + static int reverseMapPrio(int osPrio); private: struct ThreadData: public RefCountedObject @@ -119,6 +124,7 @@ private: AutoPtr pCallbackTarget; pthread_t thread; int prio; + int osPrio; Event done; std::size_t stackSize; }; @@ -144,6 +150,12 @@ inline int ThreadImpl::getPriorityImpl() const } +inline int ThreadImpl::getOSPriorityImpl() const +{ + return _pData->osPrio; +} + + inline void ThreadImpl::sleepImpl(long milliseconds) { #if defined(__VMS) || defined(__digital__) diff --git a/Foundation/include/Poco/Thread_WIN32.h b/Foundation/include/Poco/Thread_WIN32.h index ec9e43746..414cb1487 100644 --- a/Foundation/include/Poco/Thread_WIN32.h +++ b/Foundation/include/Poco/Thread_WIN32.h @@ -83,6 +83,10 @@ public: void setPriorityImpl(int prio); int getPriorityImpl() const; + void setOSPriorityImpl(int prio); + int getOSPriorityImpl() const; + static int getMinOSPriorityImpl(); + static int getMaxOSPriorityImpl(); void setStackSizeImpl(std::size_t size); std::size_t getStackSizeImpl() const; void startImpl(Runnable& target); @@ -131,6 +135,24 @@ inline int ThreadImpl::getPriorityImpl() const } +inline int ThreadImpl::getOSPriorityImpl() const +{ + return _prio; +} + + +inline int ThreadImpl::getMinOSPriorityImpl() +{ + return PRIO_LOWEST_IMPL; +} + + +inline int ThreadImpl::getMaxOSPriorityImpl() +{ + return PRIO_HIGHEST_IMPL; +} + + inline void ThreadImpl::sleepImpl(long milliseconds) { Sleep(DWORD(milliseconds)); diff --git a/Foundation/src/Thread_POSIX.cpp b/Foundation/src/Thread_POSIX.cpp index 30154cb3f..94e6cf600 100644 --- a/Foundation/src/Thread_POSIX.cpp +++ b/Foundation/src/Thread_POSIX.cpp @@ -107,6 +107,43 @@ void ThreadImpl::setPriorityImpl(int prio) } +void ThreadImpl::setOSPriorityImpl(int prio) +{ + if (prio != _pData->osPrio) + { + if (_pData->pRunnableTarget || _pData->pCallbackTarget) + { + struct sched_param par; + par.sched_priority = prio; + if (pthread_setschedparam(_pData->thread, SCHED_OTHER, &par)) + throw SystemException("cannot set thread priority"); + } + _pData->prio = reverseMapPrio(prio); + _pData->osPrio = prio; + } +} + + +int ThreadImpl::getMinOSPriorityImpl() +{ +#if defined(__VMS) || defined(__digital__) + return PRI_OTHER_MIN; +#else + return sched_get_priority_min(SCHED_OTHER); +#endif +} + + +int ThreadImpl::getMaxOSPriorityImpl() +{ +#if defined(__VMS) || defined(__digital__) + return PRI_OTHER_MAX; +#else + return sched_get_priority_max(SCHED_OTHER); +#endif +} + + void ThreadImpl::startImpl(Runnable& target) { if (_pData->pRunnableTarget) throw SystemException("thread already running"); @@ -306,4 +343,22 @@ int ThreadImpl::mapPrio(int prio) } +int ThreadImpl::reverseMapPrio(int prio) +{ + int pmin = getMinOSPriorityImpl(); + int pmax = getMaxOSPriorityImpl(); + int normal = pmin + (pmax - pmin)/2; + if (prio == pmax) + return PRIO_HIGHEST_IMPL; + if (prio > normal) + return PRIO_HIGH_IMPL; + else if (prio == normal) + return PRIO_NORMAL_IMPL; + else if (prio > pmin) + return PRIO_LOW_IMPL; + else + return PRIO_LOWEST_IMPL; +} + + } // namespace Poco diff --git a/Foundation/src/Thread_WIN32.cpp b/Foundation/src/Thread_WIN32.cpp index 39452bc6c..caaa4f79d 100644 --- a/Foundation/src/Thread_WIN32.cpp +++ b/Foundation/src/Thread_WIN32.cpp @@ -81,6 +81,12 @@ void ThreadImpl::setPriorityImpl(int prio) } +void ThreadImpl::setOSPriorityImpl(int prio) +{ + setPriorityImpl(prio); +} + + void ThreadImpl::startImpl(Runnable& target) { if (isRunningImpl())