blob: 95d1f5980f61220ec9bebd3227c0ee02250c1b78 [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "hal/Threads.h"
9
10#include <pthread.h>
11#include <sched.h>
12
13#include "hal/Errors.h"
14
15namespace hal {
16namespace init {
17void InitializeThreads() {}
18} // namespace init
19} // namespace hal
20
21extern "C" {
22
23int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
24 int32_t* status) {
25 sched_param sch;
26 int policy;
27 int success = pthread_getschedparam(
28 *reinterpret_cast<const pthread_t*>(handle), &policy, &sch);
29 if (success == 0) {
30 *status = 0;
31 } else {
32 *status = HAL_THREAD_PRIORITY_ERROR;
33 return -1;
34 }
35 if (policy == SCHED_FIFO || policy == SCHED_RR) {
36 *isRealTime = true;
37 return sch.sched_priority;
38 } else {
39 *isRealTime = false;
40 // 0 is the only suppored priority for non-realtime, so scale to 1
41 return 1;
42 }
43}
44
45int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status) {
46 auto thread = pthread_self();
47 return HAL_GetThreadPriority(&thread, isRealTime, status);
48}
49
50HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
51 int32_t priority, int32_t* status) {
52 if (handle == nullptr) {
53 *status = NULL_PARAMETER;
54 return false;
55 }
56
57 int scheduler = realTime ? SCHED_FIFO : SCHED_OTHER;
58 if (realTime) {
59 // We don't support setting priorities for non RT threads
60 // so we don't need to check for proper range
61 if (priority < sched_get_priority_min(scheduler) ||
62 priority > sched_get_priority_max(scheduler)) {
63 *status = HAL_THREAD_PRIORITY_RANGE_ERROR;
64 return false;
65 }
66 }
67
68 sched_param sch;
69 int policy;
70 pthread_getschedparam(*reinterpret_cast<const pthread_t*>(handle), &policy,
71 &sch);
72 if (scheduler == SCHED_FIFO || scheduler == SCHED_RR)
73 sch.sched_priority = priority;
74 else
75 // Only need to set 0 priority for non RT thread
76 sch.sched_priority = 0;
77 if (pthread_setschedparam(*reinterpret_cast<const pthread_t*>(handle),
78 scheduler, &sch)) {
79 *status = HAL_THREAD_PRIORITY_ERROR;
80 return false;
81 } else {
82 *status = 0;
83 return true;
84 }
85}
86
87HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
88 int32_t* status) {
89 auto thread = pthread_self();
90 return HAL_SetThreadPriority(&thread, realTime, priority, status);
91}
92
93} // extern "C"