| 
							- #pragma once
 - 
 - #ifdef ARCH_WIN
 - #include <windows.h>
 - #endif
 - 
 - #ifdef ARCH_LIN
 - #include <sys/resource.h>
 - #include <sys/types.h>
 - #include <sys/time.h>
 - #include <unistd.h>
 - #include <sys/syscall.h>
 - #include <errno.h>
 - #endif
 - 
 - class ThreadPriority
 - {
 - public:
 -     /**
 -      * Attempts to boost priority of current thread, but not all
 -      * the way to a "realtime" priority. In genera, should not require
 -      * admin rights.
 -      */
 -     static bool boostNormal();
 - 
 -     /**
 -     * Attempts to boost priority of current thread all the way to
 -     * a "realtime" priority. Will require admin rights
 -     */
 -     static bool boostRealtime();
 - 
 -     static void restore();
 - 
 - #ifdef ARCH_WIN
 -     static bool boostRealtimeWindows();
 - #endif
 - private:
 - 
 -     static bool boostNormalPthread();
 -     static bool boostRealtimePthread();
 -     static void restorePthread();
 - #ifdef ARCH_LIN
 -     static bool boostNormalLinux();
 - #endif
 - };
 - 
 - #ifdef ARCH_WIN
 - inline bool ThreadPriority::boostRealtimeWindows()
 - {
 -     HANDLE h = GetCurrentProcess();
 -     auto x = GetPriorityClass(h);
 -     printf("cur priority class = %lx, realtime=%x", x, REALTIME_PRIORITY_CLASS);
 - 
 -     SetPriorityClass(h, HIGH_PRIORITY_CLASS);
 -     printf("set pri class to %x is now %lx\n", HIGH_PRIORITY_CLASS, GetPriorityClass(h));
 - 
 -     bool b = SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
 -     int y = GetThreadPriority(GetCurrentThread());
 -     printf("set pri ret %d, is now %d want %d err=%ld\n",
 -         b,
 -         y,
 -         THREAD_PRIORITY_TIME_CRITICAL, GetLastError());
 -     fflush(stdout);
 -     return y == THREAD_PRIORITY_TIME_CRITICAL;
 - 
 - }
 - #endif
 - 
 - // Inside Visual Studio test we don't try to link in PThreads, 
 - // So they can't be used here. But they will work on all command line
 - // test builds, including Windows.
 - #if !defined(_MSC_VER) || defined(_VSCODE)
 - inline bool ThreadPriority::boostNormal()
 - {
 - #ifdef ARCH_LIN
 -     return  boostNormalLinux();
 - #else
 -     return boostNormalPthread();
 - #endif
 - }
 - 
 - inline bool ThreadPriority::boostRealtime()
 - {
 - #ifdef ARCH_WIN
 -     return boostRealtimeWindows();
 - #else
 -     return boostRealtimePthread();
 - #endif
 - }
 - 
 - inline void ThreadPriority::restore()
 - {
 -     restorePthread();
 - }
 - 
 - inline void ThreadPriority::restorePthread()
 - {
 -     const pthread_t threadHandle = pthread_self();
 -     struct sched_param params;
 -     params.sched_priority = 0;      // Note that on mac, this is not the default.
 -                                     // fix this.
 -     const int newPolicy = SCHED_OTHER;
 -     int x = pthread_setschedparam(threadHandle, newPolicy, ¶ms);
 -     if (x != 0) {
 -         printf("failed to set reset sched %d\n", x);
 -     }
 - }
 - 
 - 
 - /**
 -  * Linux doesn't support pthread priorities, so
 -  * we use the common hack of setting niceness.
 -  */
 - #ifdef ARCH_LIN
 - inline bool  ThreadPriority::boostNormalLinux()
 - {
 -     pid_t tid = syscall(SYS_gettid);
 -     const int priority = -20;
 -     int ret = setpriority(PRIO_PROCESS, tid, priority);
 -     if (ret != 0) {
 -         printf("set pri failed, errno = %d\n", errno);
 -         printf("EACCESS=%d\n", EACCES);
 -     }
 -     printf("priority now %d\n", getpriority(PRIO_PROCESS, tid));
 -     return ret == 0;
 - }
 - #endif
 - 
 - inline bool ThreadPriority::boostNormalPthread()
 - {
 -     struct sched_param params;
 -     const pthread_t threadHandle = pthread_self();
 -     int initPolicy = -10;
 -     pthread_getschedparam(threadHandle, &initPolicy, ¶ms);
 -     printf("in boost, policy was %d, pri was %d otherp=%d\n", initPolicy, params.sched_priority, SCHED_OTHER);
 - 
 -     const int initPriority = params.sched_priority;
 - 
 -     const int newPolicy = SCHED_OTHER;
 -     const int maxPriority = sched_get_priority_max(newPolicy);
 - #if 1
 -     {
 -         printf("for OTHER, pri range = %d,%d\n",
 -             sched_get_priority_min(newPolicy),
 -             sched_get_priority_max(newPolicy));
 -     }
 - #endif
 - 
 -     if (maxPriority <= initPriority) {
 -         // Linux seems to only offer one priority for SCHED_OTHER;
 -         printf("SCHED_OTHER only supports priority %d\n", maxPriority);
 -         return false;
 -     }
 - 
 -     params.sched_priority = maxPriority;
 -     int x = pthread_setschedparam(threadHandle, newPolicy, ¶ms);
 -     if (x != 0) {
 -         printf("failed to set pri %d for SCHED_OTHER. error= %d\n", maxPriority, x);
 -     }
 -     fflush(stdout);
 -     return x == 0;
 - }
 - 
 - inline bool ThreadPriority::boostRealtimePthread()
 - {
 -     struct sched_param params;
 -     const pthread_t threadHandle = pthread_self();
 -     const int newPolicy = SCHED_RR;
 -     const int maxPriority = sched_get_priority_max(newPolicy);
 -     const int minPriority = sched_get_priority_min(newPolicy);
 - 
 - 
 - #if 0
 -     if ((maxPriority <= 0) || (minPriority < 0)) {
 -         printf("algorithm doesn't work with rt %d, %d\n", minPriority, maxPriority);
 -         return false;
 -     }
 - #endif
 - 
 -     // use the mean of min and max. These should all be higher than "non realtime" 
 -     // on mac the mean was not as good as elevating as other, to let's try max/
 -     //const int newPriority = (maxPriority + minPriority) / 2;
 -     const int newPriority = maxPriority;
 - 
 -     printf("realtime min = %d max = %d will use %d\n", minPriority, maxPriority, newPriority);
 -     params.sched_priority = newPriority;
 -     int x = pthread_setschedparam(threadHandle, newPolicy, ¶ms);
 -     if (x != 0) {
 -         printf("failed to set pri %d for SCHED_RR. error= %d\n", newPriority, x);
 -     }
 -     return x == 0;
 - }
 - 
 - #else
 - inline bool ThreadPriority::boostNormal()
 - {
 -     return true;
 - }
 - 
 - inline bool ThreadPriority::boostRealtime()
 - {
 -     return true;
 - }
 - inline void ThreadPriority::restore()
 - {
 - 
 - }
 - #endif
 
 
  |