ichizok | 24714a1 | 2022-01-29 12:10:43 +0000 | [diff] [blame] | 1 | import platform |
| 2 | |
| 3 | if platform.system() == 'Darwin': |
| 4 | from ctypes import ( |
| 5 | CDLL, |
| 6 | POINTER, |
| 7 | Structure, |
| 8 | byref, |
| 9 | c_int, |
| 10 | c_uint, |
| 11 | c_uint32, |
| 12 | c_void_p, |
| 13 | sizeof |
| 14 | ) |
| 15 | from ctypes.util import find_library |
| 16 | |
| 17 | class ThreadTimeConstraintPolicy(Structure): |
| 18 | _fields_ = [ |
| 19 | ("period", c_uint32), |
| 20 | ("computation", c_uint32), |
| 21 | ("constraint", c_uint32), |
| 22 | ("preemptible", c_uint) |
| 23 | ] |
| 24 | |
| 25 | _libc = CDLL(find_library('c')) |
| 26 | |
| 27 | THREAD_TIME_CONSTRAINT_POLICY = c_uint(2) |
| 28 | |
| 29 | THREAD_TIME_CONSTRAINT_POLICY_COUNT = c_uint( |
| 30 | int(sizeof(ThreadTimeConstraintPolicy) / sizeof(c_int))) |
| 31 | |
| 32 | _libc.pthread_self.restype = c_void_p |
| 33 | |
| 34 | _libc.pthread_mach_thread_np.restype = c_uint |
| 35 | _libc.pthread_mach_thread_np.argtypes = [c_void_p] |
| 36 | |
| 37 | _libc.thread_policy_get.restype = c_int |
| 38 | _libc.thread_policy_get.argtypes = [ |
| 39 | c_uint, |
| 40 | c_uint, |
| 41 | c_void_p, |
| 42 | POINTER(c_uint), |
| 43 | POINTER(c_uint) |
| 44 | ] |
| 45 | |
| 46 | _libc.thread_policy_set.restype = c_int |
| 47 | _libc.thread_policy_set.argtypes = [ |
| 48 | c_uint, |
| 49 | c_uint, |
| 50 | c_void_p, |
| 51 | c_uint |
| 52 | ] |
| 53 | |
| 54 | def _mach_thread_self(): |
| 55 | return _libc.pthread_mach_thread_np(_libc.pthread_self()) |
| 56 | |
| 57 | def _get_time_constraint_policy(default=False): |
| 58 | thread = _mach_thread_self() |
| 59 | policy_info = ThreadTimeConstraintPolicy() |
| 60 | policy_infoCnt = THREAD_TIME_CONSTRAINT_POLICY_COUNT |
| 61 | get_default = c_uint(default) |
| 62 | |
| 63 | kret = _libc.thread_policy_get( |
| 64 | thread, |
| 65 | THREAD_TIME_CONSTRAINT_POLICY, |
| 66 | byref(policy_info), |
| 67 | byref(policy_infoCnt), |
| 68 | byref(get_default)) |
| 69 | if kret != 0: |
| 70 | return None |
| 71 | return policy_info |
| 72 | |
| 73 | def _set_time_constraint_policy(policy_info): |
| 74 | thread = _mach_thread_self() |
| 75 | policy_infoCnt = THREAD_TIME_CONSTRAINT_POLICY_COUNT |
| 76 | |
| 77 | kret = _libc.thread_policy_set( |
| 78 | thread, |
| 79 | THREAD_TIME_CONSTRAINT_POLICY, |
| 80 | byref(policy_info), |
| 81 | policy_infoCnt) |
| 82 | if kret != 0: |
| 83 | raise OSError(kret) |
| 84 | |
| 85 | def set_high_priority(): |
| 86 | policy_info = _get_time_constraint_policy(default=True) |
| 87 | if not policy_info: |
| 88 | return |
| 89 | policy_info.preemptible = c_uint(False) |
| 90 | _set_time_constraint_policy(policy_info) |