diff --git a/code/nel/include/nel/misc/p_thread.h b/code/nel/include/nel/misc/p_thread.h index cd027aa37..82f6a4ee3 100644 --- a/code/nel/include/nel/misc/p_thread.h +++ b/code/nel/include/nel/misc/p_thread.h @@ -48,6 +48,7 @@ public: virtual void wait(); virtual bool setCPUMask(uint64 cpuMask); virtual uint64 getCPUMask(); + virtual void setPriority(TThreadPriority priority); virtual std::string getUserName(); virtual IRunnable *getRunnable() diff --git a/code/nel/include/nel/misc/thread.h b/code/nel/include/nel/misc/thread.h index 82ef78a13..983e6b12a 100644 --- a/code/nel/include/nel/misc/thread.h +++ b/code/nel/include/nel/misc/thread.h @@ -68,6 +68,16 @@ public: } }; +/// Thread priorities, numbering follows Win32 for now +enum TThreadPriority +{ + ThreadPriorityLowest = -2, + ThreadPriorityLow = -1, + ThreadPriorityNormal = 0, + ThreadPriorityHigh = 1, + ThreadPriorityHighest = 2, +}; + /** * Thread base interface, must be implemented for all OS * \author Vianney Lecroart @@ -119,6 +129,9 @@ public: */ virtual uint64 getCPUMask()=0; + /// Set the thread priority. Thread must have been started before. + virtual void setPriority(TThreadPriority priority) = 0; + /** * Get the thread user name. * Under Linux return thread owner, under windows return the name of the logon user. diff --git a/code/nel/include/nel/misc/win_thread.h b/code/nel/include/nel/misc/win_thread.h index a2e8b5389..628942dde 100644 --- a/code/nel/include/nel/misc/win_thread.h +++ b/code/nel/include/nel/misc/win_thread.h @@ -49,6 +49,7 @@ public: virtual void wait(); virtual bool setCPUMask(uint64 cpuMask); virtual uint64 getCPUMask(); + virtual void setPriority(TThreadPriority priority); virtual std::string getUserName(); virtual IRunnable *getRunnable() @@ -69,8 +70,7 @@ public: void suspend(); // Resume the thread. No-op if already resumed void resume(); - // set priority as defined by "SetThreadpriority" - void setPriority(int priority); + // Priority boost void enablePriorityBoost(bool enabled); /// private use diff --git a/code/nel/src/misc/p_thread.cpp b/code/nel/src/misc/p_thread.cpp index d4f1582b4..e20981c98 100644 --- a/code/nel/src/misc/p_thread.cpp +++ b/code/nel/src/misc/p_thread.cpp @@ -207,6 +207,32 @@ uint64 CPThread::getCPUMask() return cpuMask; } +void CPThread::setPriority(TThreadPriority priority) +{ + // TODO: Verify and test this + switch (priority) + { + case ThreadPriorityHigh: + { + int minPrio = sched_get_priority_min(SCHED_FIFO); + int maxPrio = sched_get_priority_max(SCHED_FIFO); + int prio = ((maxPrio - minPrio) / 4) + minPrio; + pthread_setschedparam(_ThreadHandle, SCHED_FIFO, prio); + break; + } + case ThreadPriorityHighest: + { + int minPrio = sched_get_priority_min(SCHED_FIFO); + int maxPrio = sched_get_priority_max(SCHED_FIFO); + int prio = ((maxPrio - minPrio) / 2) + minPrio; + pthread_setschedparam(_ThreadHandle, SCHED_FIFO, prio); + break; + } + default: + pthread_setschedparam(_ThreadHandle, SCHED_OTHER, 0); + } +} + /* * getUserName */ diff --git a/code/nel/src/misc/win_thread.cpp b/code/nel/src/misc/win_thread.cpp index bbe6eccf2..f8a961a74 100644 --- a/code/nel/src/misc/win_thread.cpp +++ b/code/nel/src/misc/win_thread.cpp @@ -84,6 +84,7 @@ public: inline void enter() { EnterCriticalSection(&cs); } inline void leave() { LeaveCriticalSection(&cs); } }; +CWinCriticalSection s_CS; }/* anonymous namespace */ CWinThread::CWinThread (void* threadHandle, uint32 threadId) @@ -112,12 +113,11 @@ CWinThread::CWinThread (void* threadHandle, uint32 threadId) nlassert(0); // WARNING: following code has not tested! don't know if it work fo real ... // This is just a suggestion of a possible solution, should this situation one day occur ... // Ensure that this thread don't get deleted, or we could suspend the main thread - static CWinCriticalSection cs; - cs.enter(); + s_CS.enter(); // the 2 following statement must be executed atomicaly among the threads of the current process ! SuspendThread(threadHandle); _SuspendCount = ResumeThread(threadHandle); - cs.leave(); + s_CS.leave(); } } @@ -159,10 +159,10 @@ void CWinThread::resume() } } -void CWinThread::setPriority(int priority) +void CWinThread::setPriority(TThreadPriority priority) { nlassert(ThreadHandle); // 'start' was not called !! - BOOL result = SetThreadPriority(ThreadHandle, priority); + BOOL result = SetThreadPriority(ThreadHandle, (int)priority); nlassert(result); }