* @brief Set the priority of the current thread using the current platform's native API. This should work on Windows, Linux, and macOS. However, note that higher priorities might require elevated permissions. * * @param priority The priority to set. Must be a value from the enum `BS::os_thread_priority`. * @return `true` if the priority was set successfully, `false` otherwise. Usual
| 1237 | * @return `true` if the priority was set successfully, `false` otherwise. Usually, `false` means that the user does not have the necessary permissions to set the desired priority. |
| 1238 | */ |
| 1239 | static bool set_os_thread_priority(const os_thread_priority priority) |
| 1240 | { |
| 1241 | #if defined(_WIN32) |
| 1242 | // On Windows, this is straightforward. |
| 1243 | return SetThreadPriority(GetCurrentThread(), static_cast<int>(priority)) != 0; |
| 1244 | #elif defined(__linux__) |
| 1245 | // 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, but allowing more fine-grained control would not be portable. |
| 1246 | int policy = 0; |
| 1247 | struct sched_param param = {}; |
| 1248 | std::optional<int> nice_val = std::nullopt; |
| 1249 | switch (priority) |
| 1250 | { |
| 1251 | case os_thread_priority::realtime: |
| 1252 | // "Realtime" pre-defined priority: We use the policy `SCHED_FIFO` with the highest possible priority. |
| 1253 | policy = SCHED_FIFO; |
| 1254 | param.sched_priority = sched_get_priority_max(SCHED_FIFO); |
| 1255 | break; |
| 1256 | case os_thread_priority::highest: |
| 1257 | // "Highest" pre-defined priority: We use the policy `SCHED_RR` ("round-robin") with a priority in the middle of the available range. |
| 1258 | policy = SCHED_RR; |
| 1259 | param.sched_priority = sched_get_priority_min(SCHED_RR) + ((sched_get_priority_max(SCHED_RR) - sched_get_priority_min(SCHED_RR)) / 2); |
| 1260 | break; |
| 1261 | case os_thread_priority::above_normal: |
| 1262 | // "Above normal" pre-defined priority: We use the policy `SCHED_OTHER` (the default). This policy does not accept a priority value, so priority must be 0. However, we set the "nice" value to the minimum value as given by `PRIO_MIN`, plus 2 (which should evaluate to -18). The usual range is -20 to 19 or 20, with higher values corresponding to lower priorities. |
| 1263 | policy = SCHED_OTHER; |
| 1264 | param.sched_priority = 0; |
| 1265 | nice_val = PRIO_MIN + 2; |
| 1266 | break; |
| 1267 | case os_thread_priority::normal: |
| 1268 | // "Normal" pre-defined priority: We use the policy `SCHED_OTHER`, priority must be 0, and we set the "nice" value to 0 (the default). |
| 1269 | policy = SCHED_OTHER; |
| 1270 | param.sched_priority = 0; |
| 1271 | nice_val = 0; |
| 1272 | break; |
| 1273 | case os_thread_priority::below_normal: |
| 1274 | // "Below normal" pre-defined priority: We use the policy `SCHED_OTHER`, priority must be 0, and we set the "nice" value to half the maximum value as given by `PRIO_MAX`, rounded up (which should evaluate to 10). |
| 1275 | policy = SCHED_OTHER; |
| 1276 | param.sched_priority = 0; |
| 1277 | nice_val = (PRIO_MAX / 2) + (PRIO_MAX % 2); |
| 1278 | break; |
| 1279 | case os_thread_priority::lowest: |
| 1280 | // "Lowest" pre-defined priority: We use the policy `SCHED_OTHER`, priority must be 0, and we set the "nice" value to the maximum value as given by `PRIO_MAX`, minus 3 (which should evaluate to 17). |
| 1281 | policy = SCHED_OTHER; |
| 1282 | param.sched_priority = 0; |
| 1283 | nice_val = PRIO_MAX - 3; |
| 1284 | break; |
| 1285 | case os_thread_priority::idle: |
| 1286 | // "Idle" pre-defined priority on Linux: We use the policy `SCHED_IDLE`, priority must be 0, and we don't touch the "nice" value. |
| 1287 | policy = SCHED_IDLE; |
| 1288 | param.sched_priority = 0; |
| 1289 | break; |
| 1290 | default: |
| 1291 | return false; |
| 1292 | } |
| 1293 | bool success = (pthread_setschedparam(pthread_self(), policy, ¶m) == 0); |
| 1294 | if (nice_val.has_value()) |
| 1295 | success = success && (setpriority(PRIO_PROCESS, static_cast<id_t>(syscall(SYS_gettid)), nice_val.value()) == 0); |
| 1296 | return success; |
nothing calls this directly
no outgoing calls
no test coverage detected