blob: aa55b56945be48f73756f85ba65d4d4e9d09d4e0 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "hal/Threads.h"
6
7#include <pthread.h>
8#include <sched.h>
9
10#include "hal/Errors.h"
11
Austin Schuh812d0d12021-11-04 20:16:48 -070012namespace hal::init {
Brian Silverman8fce7482020-01-05 13:18:21 -080013void InitializeThreads() {}
Austin Schuh812d0d12021-11-04 20:16:48 -070014} // namespace hal::init
Brian Silverman8fce7482020-01-05 13:18:21 -080015
16extern "C" {
17
18int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
19 int32_t* status) {
20 sched_param sch;
21 int policy;
22 int success = pthread_getschedparam(
23 *reinterpret_cast<const pthread_t*>(handle), &policy, &sch);
24 if (success == 0) {
25 *status = 0;
26 } else {
27 *status = HAL_THREAD_PRIORITY_ERROR;
28 return -1;
29 }
30 if (policy == SCHED_FIFO || policy == SCHED_RR) {
31 *isRealTime = true;
32 return sch.sched_priority;
33 } else {
34 *isRealTime = false;
Austin Schuh812d0d12021-11-04 20:16:48 -070035 // 0 is the only supported priority for non-real-time
36 return 0;
Brian Silverman8fce7482020-01-05 13:18:21 -080037 }
38}
39
40int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status) {
41 auto thread = pthread_self();
42 return HAL_GetThreadPriority(&thread, isRealTime, status);
43}
44
45HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
46 int32_t priority, int32_t* status) {
47 if (handle == nullptr) {
48 *status = NULL_PARAMETER;
49 return false;
50 }
51
52 int scheduler = realTime ? SCHED_FIFO : SCHED_OTHER;
53 if (realTime) {
54 // We don't support setting priorities for non RT threads
55 // so we don't need to check for proper range
56 if (priority < sched_get_priority_min(scheduler) ||
57 priority > sched_get_priority_max(scheduler)) {
58 *status = HAL_THREAD_PRIORITY_RANGE_ERROR;
59 return false;
60 }
61 }
62
63 sched_param sch;
64 int policy;
65 pthread_getschedparam(*reinterpret_cast<const pthread_t*>(handle), &policy,
66 &sch);
Austin Schuh812d0d12021-11-04 20:16:48 -070067 if (scheduler == SCHED_FIFO || scheduler == SCHED_RR) {
Brian Silverman8fce7482020-01-05 13:18:21 -080068 sch.sched_priority = priority;
Austin Schuh812d0d12021-11-04 20:16:48 -070069 } else {
Brian Silverman8fce7482020-01-05 13:18:21 -080070 // Only need to set 0 priority for non RT thread
71 sch.sched_priority = 0;
Austin Schuh812d0d12021-11-04 20:16:48 -070072 }
73
Brian Silverman8fce7482020-01-05 13:18:21 -080074 if (pthread_setschedparam(*reinterpret_cast<const pthread_t*>(handle),
75 scheduler, &sch)) {
76 *status = HAL_THREAD_PRIORITY_ERROR;
77 return false;
78 } else {
79 *status = 0;
80 return true;
81 }
82}
83
84HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
85 int32_t* status) {
86 auto thread = pthread_self();
87 return HAL_SetThreadPriority(&thread, realTime, priority, status);
88}
89
90} // extern "C"