Page 1 of 1

ThreadPriority() for Linux+OSX (code provided)

Posted: Sun Nov 29, 2015 9:31 am
by Keya
hello, currently PB's native ThreadPriority() function only supports Windows, it would be nice if supported Linux + Mac OSX

in the meantime ive put together the following code to achieve this, tested on Linux Mint 32+64 and Mac OSX El Capitan 64.

It just requires a call to pthread_getschedparam() to get the threads policy, then pthread_setschedparam() to adjust the priority while retaining the same policy. It's a lot easier than my verbose demo makes it look anyway heehee

btw the PB docs for ThreadPriority() say that the priority can be up to 32 which is correct for Windows, but note that on Linux it's up to 99, and on my Mac OSX i get Min=15 Max=47, even when run from sudo :)

Code: Select all

Structure sched_param
  sched_priority.i
EndStructure

ImportC ""
  pthread_self()
  sched_get_priority_min(policy.i) 
  sched_get_priority_max(policy.i)  
  pthread_getschedparam(thread.i,*policy,*param.sched_param)
  pthread_setschedparam(thread.i,policy.i,*param.sched_param)
EndImport

#SCHED_NORMAL = 0
#SCHED_FIFO = 1
#SCHED_RR = 2
#SCHED_BATCH = 3
#SCHED_IDLE = 5       ;reserved
#SCHED_DEADLINE = 6   ;reserved

;/usr/include/asm/errno.h ...
#EPERM  = 1    ;/* Operation not permitted */
#EINVAL = 22   ;/* Invalid argument */
#ESRCH  = 3    ;/* No such process */


Procedure.s GetThreadParamErrMsg(errnum.i)
  Select errnum
    Case #EPERM: ProcedureReturn "The caller does not have appropriate privileges to set the specified scheduling policy and parameters"
    Case #EINVAL: ProcedureReturn "policy is not a recognized policy, or param does not make sense for the policy"
    Case #ESRCH: ProcedureReturn "No thread with the ID thread could be found"
    Default: ProcedureReturn "Unknown error"
  EndSelect
EndProcedure


Define policy.i, param.sched_param, result.i

;Determine MIN & MAX priority levels. Typically 1-99 for SCHED_FIFO/SCHED_RR, 0 for SCHED_OTHER/SCHED_BATCH
policy = #SCHED_NORMAL
PrintN("MIN Priority = " + Str(sched_get_priority_min(policy)))  ;-1 on error
PrintN("MAX Priority = " + Str(sched_get_priority_max(policy)))  ;-1 on error


;GET the existing policy & priority
result = pthread_getschedparam(pthread_self(), @policy, @param)
If result <> 0
  PrintN("Failed to GET thread priority - Error=" + GetThreadParamErrMsg(result))
Else
  PrintN("BEFORE: Policy=" + Str(policy) + " Priority=" + Str(param\sched_priority))
EndIf


;SET the priority and/or policy
param\sched_priority = 20
result = pthread_setschedparam(pthread_self(), policy, @param)
If result <> 0
  PrintN("Failed to SET thread priority - Error=" + GetThreadParamErrMsg(result))
Else
  PrintN("Successfully set thread priority")
EndIf


;CHECK to confirm the change was successful
result = pthread_getschedparam(pthread_self(), @policy, @param)
If result <> 0
  PrintN("Failed to GET thread priority - Error=" + GetThreadParamErrMsg(result))
Else
  PrintN("AFTER: Policy=" + Str(policy) + " Priority=" + Str(param\sched_priority))
EndIf


Input()
End

; IDE Options = PureBasic 5.41 LTS Beta 1 (Linux - x86)
; ExecutableFormat = Console
; DisableDebugger