MCPcopy Create free account
hub / github.com/bshoshany/thread-pool / get_os_thread_priority

Method get_os_thread_priority

include/BS_thread_pool.hpp:1143–1231  ·  view source on GitHub ↗

* @brief Get the priority of the current thread using the current platform's native API. This should work on Windows, Linux, and macOS. * * @return An `std::optional` object, optionally containing the priority of the current thread, as a member of the enum `BS::os_thread_priority`. If the returned object does not contain a value, then either the priority could not be determined, or it is

Source from the content-addressed store, hash-verified

1141 * @return An `std::optional` object, optionally containing the priority of the current thread, as a member of the enum `BS::os_thread_priority`. If the returned object does not contain a value, then either the priority could not be determined, or it is not one of the pre-defined values.
1142 */
1143 [[nodiscard]] static std::optional<os_thread_priority> get_os_thread_priority()
1144 {
1145 #if defined(_WIN32)
1146 // On Windows, this is straightforward.
1147 const int priority = GetThreadPriority(GetCurrentThread());
1148 if (priority == THREAD_PRIORITY_ERROR_RETURN)
1149 return std::nullopt;
1150 return static_cast<os_thread_priority>(priority);
1151 #elif defined(__linux__)
1152 // On Linux, we distill the choices of scheduling policy, priority, and "nice" value into 7 pre-defined levels, for simplicity and portability. The total number of possible combinations of policies and priorities is much larger, so if the value was set via any means other than `BS::this_thread::set_os_thread_priority()`, it may not match one of our pre-defined values.
1153 int policy = 0;
1154 struct sched_param param = {};
1155 if (pthread_getschedparam(pthread_self(), &policy, &param) != 0)
1156 return std::nullopt;
1157 if (policy == SCHED_FIFO && param.sched_priority == sched_get_priority_max(SCHED_FIFO))
1158 {
1159 // The only pre-defined priority that uses SCHED_FIFO and the maximum available priority value is the "realtime" priority.
1160 return os_thread_priority::realtime;
1161 }
1162 if (policy == SCHED_RR && param.sched_priority == sched_get_priority_min(SCHED_RR) + ((sched_get_priority_max(SCHED_RR) - sched_get_priority_min(SCHED_RR)) / 2))
1163 {
1164 // The only pre-defined priority that uses SCHED_RR and a priority in the middle of the available range is the "highest" priority.
1165 return os_thread_priority::highest;
1166 }
1167 #ifdef __linux__
1168 if (policy == SCHED_IDLE)
1169 {
1170 // The only pre-defined priority that uses SCHED_IDLE is the "idle" priority. Note that this scheduling policy is not available on macOS.
1171 return os_thread_priority::idle;
1172 }
1173 #endif
1174 if (policy == SCHED_OTHER)
1175 {
1176 // For SCHED_OTHER, the result depends on the "nice" value. The usual range is -20 to 19 or 20, with higher values corresponding to lower priorities. Note that `getpriority()` returns -1 on error, but since this does not correspond to any of our pre-defined values, this function will return `std::nullopt` anyway.
1177 const int nice_val = getpriority(PRIO_PROCESS, static_cast<id_t>(syscall(SYS_gettid)));
1178 switch (nice_val)
1179 {
1180 case PRIO_MIN + 2:
1181 return os_thread_priority::above_normal;
1182 case 0:
1183 return os_thread_priority::normal;
1184 case (PRIO_MAX / 2) + (PRIO_MAX % 2):
1185 return os_thread_priority::below_normal;
1186 case PRIO_MAX - 3:
1187 return os_thread_priority::lowest;
1188 #ifdef __APPLE__
1189 // `SCHED_IDLE` doesn't exist on macOS, so we use the policy `SCHED_OTHER` with a "nice" value of `PRIO_MAX - 2`.
1190 case PRIO_MAX - 2:
1191 return os_thread_priority::idle;
1192 #endif
1193 default:
1194 return std::nullopt;
1195 }
1196 }
1197 return std::nullopt;
1198 #elif defined(__APPLE__)
1199 // On macOS, we distill the choices of scheduling policy and priority into 7 pre-defined levels, for simplicity and portability. The total number of possible combinations of policies and priorities is much larger, so if the value was set via any means other than `BS::this_thread::set_os_thread_priority()`, it may not match one of our pre-defined values.
1200 int policy = 0;

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected