diff --git a/design-docs/real-time-thread-priorities.md b/design-docs/real-time-thread-priorities.md new file mode 100644 index 0000000000..01b69c24df --- /dev/null +++ b/design-docs/real-time-thread-priorities.md @@ -0,0 +1,6 @@ +# Real-time thread priorities + +|Name |Location |Priority| +|-------------------|---------------------------------------------------------------------------------------------|--------| +|CAN HAL thread |[hal/src/main/native/systemcore/CAN.cpp](../hal/src/main/native/systemcore/CAN.cpp) |50 | +|Notifier HAL thread|[hal/src/main/native/systemcore/Notifier.cpp](../hal/src/main/native/systemcore/Notifier.cpp)|40 | diff --git a/hal/src/main/java/org/wpilib/hardware/hal/NotifierJNI.java b/hal/src/main/java/org/wpilib/hardware/hal/NotifierJNI.java index e904f0d444..53ac65b34b 100644 --- a/hal/src/main/java/org/wpilib/hardware/hal/NotifierJNI.java +++ b/hal/src/main/java/org/wpilib/hardware/hal/NotifierJNI.java @@ -24,22 +24,6 @@ public class NotifierJNI extends JNIWrapper { */ public static native int createNotifier(); - /** - * Sets the HAL notifier thread priority. - * - *

The HAL notifier thread is responsible for managing the system's notifier interrupt and - * waking up user's Notifiers when it's their time to run. Giving the HAL notifier thread - * real-time priority helps ensure the user's real-time Notifiers, if any, are notified to run in - * a timely manner. - * - * @param realTime Set to true to set a real-time priority, false for standard priority. - * @param priority Priority to set the thread to. For real-time, this is 1-99 with 99 being - * highest. For non-real-time, this is forced to 0. See "man 7 sched" for more details. - * @return True on success. - * @see "HAL_SetNotifierThreadPriority" - */ - public static native boolean setHALThreadPriority(boolean realTime, int priority); - /** * Sets the name of the notifier. * diff --git a/hal/src/main/java/org/wpilib/hardware/hal/ThreadsJNI.java b/hal/src/main/java/org/wpilib/hardware/hal/ThreadsJNI.java index 1ce2bc2e0f..1998c3837b 100644 --- a/hal/src/main/java/org/wpilib/hardware/hal/ThreadsJNI.java +++ b/hal/src/main/java/org/wpilib/hardware/hal/ThreadsJNI.java @@ -11,32 +11,27 @@ package org.wpilib.hardware.hal; */ public class ThreadsJNI extends JNIWrapper { /** - * Gets the thread priority for the current thread. + * Gets the current thread's priority. * - * @return The current thread priority. For real-time, this is 1-99 with 99 being highest. For - * non-real-time, this is 0. See "man 7 sched" for details. + *

Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, and 99 is + * highest priority. See "man 7 sched" for details. + * + * @return The current thread's priority. * @see "HAL_GetCurrentThreadPriority" */ public static native int getCurrentThreadPriority(); /** - * Gets the real-time status for the current thread. + * Sets the current thread's priority. * - * @return Set to true if thread is real-time, otherwise false. - * @see "HAL_GetCurrentThreadPriority" - */ - public static native boolean getCurrentThreadIsRealTime(); - - /** - * Sets the thread priority for the current thread. + *

Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, and 99 is + * highest priority. See "man 7 sched" for details. * - * @param realTime Set to true to set a real-time priority, false for standard priority. - * @param priority Priority to set the thread to. For real-time, this is 1-99 with 99 being - * highest. For non-real-time, this is forced to 0. See "man 7 sched" for more details. + * @param priority The priority. * @return True on success. * @see "HAL_SetCurrentThreadPriority" */ - public static native boolean setCurrentThreadPriority(boolean realTime, int priority); + public static native boolean setCurrentThreadPriority(int priority); /** Utility class. */ private ThreadsJNI() {} diff --git a/hal/src/main/native/cpp/jni/NotifierJNI.cpp b/hal/src/main/native/cpp/jni/NotifierJNI.cpp index e4dd9a5e00..92cefa1a20 100644 --- a/hal/src/main/native/cpp/jni/NotifierJNI.cpp +++ b/hal/src/main/native/cpp/jni/NotifierJNI.cpp @@ -3,9 +3,9 @@ // the WPILib BSD license file in the root directory of this project. #include +#include #include -#include #include "HALUtil.hpp" #include "org_wpilib_hardware_hal_NotifierJNI.h" @@ -33,20 +33,7 @@ Java_org_wpilib_hardware_hal_NotifierJNI_createNotifier return 0; // something went wrong in HAL } - return (jint)notifierHandle; -} - -/* - * Class: org_wpilib_hardware_hal_NotifierJNI - * Method: setHALThreadPriority - * Signature: (ZI)Z - */ -JNIEXPORT jboolean JNICALL -Java_org_wpilib_hardware_hal_NotifierJNI_setHALThreadPriority - (JNIEnv* env, jclass, jboolean realTime, jint priority) -{ - int32_t status = 0; - return HAL_SetNotifierThreadPriority(realTime, priority, &status); + return static_cast(notifierHandle); } /* @@ -140,7 +127,7 @@ Java_org_wpilib_hardware_hal_NotifierJNI_getNotifierOverrun CheckStatus(env, status); - return (jint)count; + return static_cast(count); } } // extern "C" diff --git a/hal/src/main/native/cpp/jni/ThreadsJNI.cpp b/hal/src/main/native/cpp/jni/ThreadsJNI.cpp index 6f07a7e073..8ae4e334ea 100644 --- a/hal/src/main/native/cpp/jni/ThreadsJNI.cpp +++ b/hal/src/main/native/cpp/jni/ThreadsJNI.cpp @@ -3,6 +3,7 @@ // the WPILib BSD license file in the root directory of this project. #include +#include #include @@ -13,6 +14,7 @@ using namespace wpi::hal; extern "C" { + /* * Class: org_wpilib_hardware_hal_ThreadsJNI * Method: getCurrentThreadPriority @@ -22,43 +24,25 @@ JNIEXPORT jint JNICALL Java_org_wpilib_hardware_hal_ThreadsJNI_getCurrentThreadPriority (JNIEnv* env, jclass) { - int32_t status = 0; - HAL_Bool isRT = false; - auto ret = HAL_GetCurrentThreadPriority(&isRT, &status); + int32_t priority = 0; + HAL_Status status = HAL_GetCurrentThreadPriority(&priority); CheckStatus(env, status); - return static_cast(ret); -} - -/* - * Class: org_wpilib_hardware_hal_ThreadsJNI - * Method: getCurrentThreadIsRealTime - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL -Java_org_wpilib_hardware_hal_ThreadsJNI_getCurrentThreadIsRealTime - (JNIEnv* env, jclass) -{ - int32_t status = 0; - HAL_Bool isRT = false; - HAL_GetCurrentThreadPriority(&isRT, &status); - CheckStatus(env, status); - return static_cast(isRT); + return static_cast(priority); } /* * Class: org_wpilib_hardware_hal_ThreadsJNI * Method: setCurrentThreadPriority - * Signature: (ZI)Z + * Signature: (I)Z */ JNIEXPORT jboolean JNICALL Java_org_wpilib_hardware_hal_ThreadsJNI_setCurrentThreadPriority - (JNIEnv* env, jclass, jboolean realTime, jint priority) + (JNIEnv* env, jclass, jint priority) { - int32_t status = 0; - auto ret = HAL_SetCurrentThreadPriority( - static_cast(realTime), static_cast(priority), &status); + HAL_Status status = + HAL_SetCurrentThreadPriority(static_cast(priority)); CheckStatus(env, status, false); - return static_cast(ret); + return static_cast(status); } } // extern "C" diff --git a/hal/src/main/native/include/wpi/hal/Notifier.h b/hal/src/main/native/include/wpi/hal/Notifier.h index 9d6981e10e..c914bbdf49 100644 --- a/hal/src/main/native/include/wpi/hal/Notifier.h +++ b/hal/src/main/native/include/wpi/hal/Notifier.h @@ -30,25 +30,6 @@ extern "C" { */ HAL_NotifierHandle HAL_CreateNotifier(int32_t* status); -/** - * Sets the HAL notifier thread priority. - * - * The HAL notifier thread is responsible for managing the system's notifier - * interrupt and waking up user's Notifiers when it's their time to run. - * Giving the HAL notifier thread real-time priority helps ensure the user's - * real-time Notifiers, if any, are notified to run in a timely manner. - * - * @param[in] realTime Set to true to set a real-time priority, false for - * standard priority. - * @param[in] priority Priority to set the thread to. For real-time, this is - * 1-99 with 99 being highest. For non-real-time, this is - * forced to 0. See "man 7 sched" for more details. - * @param[out] status Error status variable. 0 on success. - * @return True on success. - */ -HAL_Bool HAL_SetNotifierThreadPriority(HAL_Bool realTime, int32_t priority, - int32_t* status); - /** * Sets the name of a notifier. * diff --git a/hal/src/main/native/include/wpi/hal/Threads.h b/hal/src/main/native/include/wpi/hal/Threads.h index 3ae46ac410..106c999920 100644 --- a/hal/src/main/native/include/wpi/hal/Threads.h +++ b/hal/src/main/native/include/wpi/hal/Threads.h @@ -4,6 +4,8 @@ #pragma once +#include + #include "wpi/hal/Types.h" /** @@ -19,58 +21,50 @@ extern "C" { #endif /** - * Gets the thread priority for the specified thread. + * Gets the specified thread's priority. * - * @param[in] handle Native handle pointer to the thread to get the - * priority for. - * @param[out] isRealTime Set to true if thread is real-time, otherwise false. - * @param[out] status Error status variable. 0 on success. - * @return The current thread priority. For real-time, this is 1-99 with 99 - * being highest. For non-real-time, this is 0. See "man 7 sched" for - * details. + * Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, + * and 99 is highest priority. See "man 7 sched" for details. + * + * @param[in] handle Native thread handle. + * @param[out] priority The specified thread's priority. + * @return Error status variable. 0 on success. */ -int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime, - int32_t* status); +HAL_Status HAL_GetThreadPriority(NativeThreadHandle handle, int32_t* priority); /** - * Gets the thread priority for the current thread. + * Gets the current thread's priority. * - * @param[out] isRealTime Set to true if thread is real-time, otherwise false. - * @param[out] status Error status variable. 0 on success. - * @return The current thread priority. For real-time, this is 1-99 with 99 - * being highest. For non-real-time, this is 0. See "man 7 sched" for - * details. + * Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, + * and 99 is highest priority. See "man 7 sched" for details. + * + * @param[out] priority The current thread's priority. + * @return Error status variable. 0 on success. */ -int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status); +HAL_Status HAL_GetCurrentThreadPriority(int32_t* priority); /** - * Sets the thread priority for the specified thread. + * Sets the specified thread's priority. * - * @param[in] handle Reference to the thread to set the priority of. - * @param[in] realTime Set to true to set a real-time priority, false for - * standard priority. - * @param[in] priority Priority to set the thread to. For real-time, this is - * 1-99 with 99 being highest. For non-real-time, this is - * forced to 0. See "man 7 sched" for more details. - * @param[out] status Error status variable. 0 on success. - * @return True on success. + * Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, + * and 99 is highest priority. See "man 7 sched" for details. + * + * @param[in] handle The native thread handle. + * @param[in] priority The priority. + * @return Error status variable. 0 on success. */ -HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime, - int32_t priority, int32_t* status); +HAL_Status HAL_SetThreadPriority(NativeThreadHandle handle, int32_t priority); /** - * Sets the thread priority for the current thread. + * Sets the current thread's priority. * - * @param[in] realTime Set to true to set a real-time priority, false for - * standard priority. - * @param[in] priority Priority to set the thread to. For real-time, this is - * 1-99 with 99 being highest. For non-real-time, this is - * forced to 0. See "man 7 sched" for more details. - * @param[out] status Error status variable. 0 on success. - * @return True on success. + * Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, + * and 99 is highest priority. See "man 7 sched" for details. + * + * @param[in] priority The priority. + * @return Error status variable. 0 on success. */ -HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority, - int32_t* status); +HAL_Status HAL_SetCurrentThreadPriority(int32_t priority); #ifdef __cplusplus } // extern "C" diff --git a/hal/src/main/native/sim/Notifier.cpp b/hal/src/main/native/sim/Notifier.cpp index c079c8ddbc..e7f7066cc0 100644 --- a/hal/src/main/native/sim/Notifier.cpp +++ b/hal/src/main/native/sim/Notifier.cpp @@ -224,12 +224,6 @@ HAL_NotifierHandle HAL_CreateNotifier(int32_t* status) { return handle; } -HAL_Bool HAL_SetNotifierThreadPriority(HAL_Bool realTime, int32_t priority, - int32_t* status) { - auto native = notifierInstance->owner.GetNativeThreadHandle(); - return HAL_SetThreadPriority(&native, realTime, priority, status); -} - void HAL_SetNotifierName(HAL_NotifierHandle notifierHandle, const WPI_String* name, int32_t* status) { auto thr = notifierInstance->owner.GetThread(); diff --git a/hal/src/main/native/sim/Threads.cpp b/hal/src/main/native/sim/Threads.cpp index bd982bdec6..37e504b685 100644 --- a/hal/src/main/native/sim/Threads.cpp +++ b/hal/src/main/native/sim/Threads.cpp @@ -4,22 +4,28 @@ #include "wpi/hal/Threads.h" +#include + +#include "wpi/hal/Types.h" + namespace wpi::hal::init { void InitializeThreads() {} } // namespace wpi::hal::init -int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime, - int32_t* status) { +HAL_Status HAL_GetThreadPriority(NativeThreadHandle handle, int32_t* priority) { + *priority = 0; return 0; } -int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status) { + +HAL_Status HAL_GetCurrentThreadPriority(int32_t* priority) { + *priority = 0; return 0; } -HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime, - int32_t priority, int32_t* status) { - return true; + +HAL_Status HAL_SetThreadPriority(NativeThreadHandle handle, int32_t priority) { + return 0; } -HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority, - int32_t* status) { - return true; + +HAL_Status HAL_SetCurrentThreadPriority(int32_t priority) { + return 0; } diff --git a/hal/src/main/native/systemcore/CAN.cpp b/hal/src/main/native/systemcore/CAN.cpp index a7956f4e61..9583493551 100644 --- a/hal/src/main/native/systemcore/CAN.cpp +++ b/hal/src/main/native/systemcore/CAN.cpp @@ -149,9 +149,7 @@ void CANStreamStorage::CheckFrame(const HAL_CANStreamMessage& message) { bool SocketCanState::InitializeBuses() { bool success = true; readLoopRunner.ExecSync([this, &success](wpi::net::uv::Loop& loop) { - int32_t status = 0; - HAL_SetCurrentThreadPriority(true, 50, &status); - if (status != 0) { + if (HAL_SetCurrentThreadPriority(50) != 0) { wpi::util::print("Failed to set CAN thread priority\n"); } diff --git a/hal/src/main/native/systemcore/Notifier.cpp b/hal/src/main/native/systemcore/Notifier.cpp index 839204aa68..f80e220004 100644 --- a/hal/src/main/native/systemcore/Notifier.cpp +++ b/hal/src/main/native/systemcore/Notifier.cpp @@ -20,6 +20,7 @@ #include "wpi/hal/handles/UnlimitedHandleResource.hpp" #include "wpi/util/SafeThread.hpp" #include "wpi/util/Synchronization.hpp" +#include "wpi/util/print.hpp" #include "wpi/util/priority_queue.hpp" #include "wpi/util/string.hpp" @@ -74,6 +75,10 @@ void InitializeNotifier() { } // namespace wpi::hal::init void NotifierThread::Main() { + if (HAL_SetCurrentThreadPriority(40) != 0) { + wpi::util::print("Failed to set HAL Notifier thread priority\n"); + } + std::unique_lock lock(m_mutex); while (m_active) { if (m_alarmQueue.empty()) { @@ -150,12 +155,6 @@ HAL_NotifierHandle HAL_CreateNotifier(int32_t* status) { return handle; } -HAL_Bool HAL_SetNotifierThreadPriority(HAL_Bool realTime, int32_t priority, - int32_t* status) { - auto native = notifierInstance->owner.GetNativeThreadHandle(); - return HAL_SetThreadPriority(&native, realTime, priority, status); -} - void HAL_SetNotifierName(HAL_NotifierHandle notifierHandle, const WPI_String* name, int32_t* status) { auto thr = notifierInstance->owner.GetThread(); diff --git a/hal/src/main/native/systemcore/Threads.cpp b/hal/src/main/native/systemcore/Threads.cpp index dd1a5ab6f8..1da3ad9c7d 100644 --- a/hal/src/main/native/systemcore/Threads.cpp +++ b/hal/src/main/native/systemcore/Threads.cpp @@ -4,10 +4,13 @@ #include "wpi/hal/Threads.h" +#include + #include #include #include "wpi/hal/Errors.h" +#include "wpi/hal/Types.h" namespace wpi::hal::init { void InitializeThreads() {} @@ -15,76 +18,55 @@ void InitializeThreads() {} extern "C" { -int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime, - int32_t* status) { +HAL_Status HAL_GetThreadPriority(NativeThreadHandle handle, int32_t* priority) { + if (handle == nullptr) { + return NULL_PARAMETER; + } + sched_param sch; int policy; - int success = pthread_getschedparam( - *reinterpret_cast(handle), &policy, &sch); - if (success == 0) { - *status = 0; - } else { - *status = HAL_THREAD_PRIORITY_ERROR; - return -1; - } - if (policy == SCHED_FIFO || policy == SCHED_RR) { - *isRealTime = true; - return sch.sched_priority; - } else { - *isRealTime = false; - // 0 is the only supported priority for non-real-time + if (pthread_getschedparam(*reinterpret_cast(handle), + &policy, &sch) == 0) { + *priority = sch.sched_priority; return 0; + } else { + return HAL_THREAD_PRIORITY_ERROR; } } -int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status) { +HAL_Status HAL_GetCurrentThreadPriority(int32_t* priority) { auto thread = pthread_self(); - return HAL_GetThreadPriority(&thread, isRealTime, status); + return HAL_GetThreadPriority(&thread, priority); } -HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime, - int32_t priority, int32_t* status) { +HAL_Status HAL_SetThreadPriority(NativeThreadHandle handle, int32_t priority) { if (handle == nullptr) { - *status = NULL_PARAMETER; - return false; + return NULL_PARAMETER; } - int scheduler = realTime ? SCHED_FIFO : SCHED_OTHER; - if (realTime) { - // We don't support setting priorities for non RT threads - // so we don't need to check for proper range - if (priority < sched_get_priority_min(scheduler) || - priority > sched_get_priority_max(scheduler)) { - *status = HAL_THREAD_PRIORITY_RANGE_ERROR; - return false; - } + if (priority < 0 || priority > 99) { + return HAL_THREAD_PRIORITY_RANGE_ERROR; } + int scheduler = priority > 0 ? SCHED_RR : SCHED_OTHER; + sched_param sch; int policy; pthread_getschedparam(*reinterpret_cast(handle), &policy, &sch); - if (scheduler == SCHED_FIFO || scheduler == SCHED_RR) { - sch.sched_priority = priority; - } else { - // Only need to set 0 priority for non RT thread - sch.sched_priority = 0; - } + sch.sched_priority = priority; if (pthread_setschedparam(*reinterpret_cast(handle), scheduler, &sch)) { - *status = HAL_THREAD_PRIORITY_ERROR; - return false; + return HAL_THREAD_PRIORITY_ERROR; } else { - *status = 0; - return true; + return 0; } } -HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority, - int32_t* status) { +HAL_Status HAL_SetCurrentThreadPriority(int32_t priority) { auto thread = pthread_self(); - return HAL_SetThreadPriority(&thread, realTime, priority, status); + return HAL_SetThreadPriority(&thread, priority); } } // extern "C" diff --git a/hal/src/main/python/semiwrap/Notifier_c.yml b/hal/src/main/python/semiwrap/Notifier_c.yml index 6bb7b0273f..d35d17f3aa 100644 --- a/hal/src/main/python/semiwrap/Notifier_c.yml +++ b/hal/src/main/python/semiwrap/Notifier_c.yml @@ -10,4 +10,3 @@ functions: HAL_CancelNotifierAlarm: HAL_GetNotifierOverrun: HAL_AcknowledgeNotifierAlarm: - HAL_SetNotifierThreadPriority: diff --git a/wpilibc/src/main/native/cpp/system/Notifier.cpp b/wpilibc/src/main/native/cpp/system/Notifier.cpp index 5cb975e56f..03bca34dc6 100644 --- a/wpilibc/src/main/native/cpp/system/Notifier.cpp +++ b/wpilibc/src/main/native/cpp/system/Notifier.cpp @@ -14,56 +14,20 @@ using namespace wpi; -Notifier::Notifier(std::function callback) { - if (!callback) { - throw WPILIB_MakeError(err::NullParameter, "callback"); - } - m_callback = callback; - int32_t status = 0; - m_notifier = HAL_CreateNotifier(&status); - WPILIB_CheckErrorStatus(status, "CreateNotifier"); - - m_thread = std::thread([=, this] { - for (;;) { - int32_t status = 0; - HAL_NotifierHandle notifier = m_notifier.load(); - if (notifier == 0) { - break; - } - if (WPI_WaitForObject(notifier) == 0) { - break; - } - - std::function callback; - { - std::scoped_lock lock(m_processMutex); - callback = m_callback; - } - - // Call callback - if (callback) { - callback(); - } - - // Ack notifier - HAL_AcknowledgeNotifierAlarm(notifier, &status); - WPILIB_CheckErrorStatus(status, "AcknowledgeNotifier"); - } - }); -} - Notifier::Notifier(int priority, std::function callback) { if (!callback) { throw WPILIB_MakeError(err::NullParameter, "callback"); } m_callback = callback; - int32_t status = 0; + HAL_Status status = 0; m_notifier = HAL_CreateNotifier(&status); WPILIB_CheckErrorStatus(status, "InitializeNotifier"); m_thread = std::thread([=, this] { - int32_t status = 0; - HAL_SetCurrentThreadPriority(true, priority, &status); + if (priority > 0 && HAL_SetCurrentThreadPriority(priority) != 0) { + WPILIB_ReportWarning("Setting Notifier priority to {} failed\n", + priority); + } for (;;) { HAL_NotifierHandle notifier = m_notifier.load(); if (notifier == 0) { @@ -99,6 +63,7 @@ Notifier::Notifier(int priority, std::function callback) { } // Ack notifier + HAL_Status status = 0; HAL_AcknowledgeNotifierAlarm(notifier, &status); WPILIB_CheckErrorStatus(status, "AcknowledgeNotifier"); } @@ -170,8 +135,3 @@ int32_t Notifier::GetOverrun() const { WPILIB_CheckErrorStatus(status, "GetNotifierOverrun"); return overrun; } - -bool Notifier::SetHALThreadPriority(bool realTime, int32_t priority) { - int32_t status = 0; - return HAL_SetNotifierThreadPriority(realTime, priority, &status); -} diff --git a/wpilibc/src/main/native/cpp/system/Threads.cpp b/wpilibc/src/main/native/cpp/system/Threads.cpp index 9f90af0459..9f1dcae4ba 100644 --- a/wpilibc/src/main/native/cpp/system/Threads.cpp +++ b/wpilibc/src/main/native/cpp/system/Threads.cpp @@ -9,38 +9,32 @@ namespace wpi { -int GetThreadPriority(std::thread& thread, bool* isRealTime) { - int32_t status = 0; - HAL_Bool rt = false; +int GetThreadPriority(std::thread& thread) { auto native = thread.native_handle(); - auto ret = HAL_GetThreadPriority(&native, &rt, &status); + int32_t priority = 0; + HAL_Status status = HAL_GetThreadPriority(&native, &priority); WPILIB_CheckErrorStatus(status, "GetThreadPriority"); - *isRealTime = rt; - return ret; + return priority; } -int GetCurrentThreadPriority(bool* isRealTime) { - int32_t status = 0; - HAL_Bool rt = false; - auto ret = HAL_GetCurrentThreadPriority(&rt, &status); +int GetCurrentThreadPriority() { + int32_t priority = 0; + HAL_Status status = HAL_GetCurrentThreadPriority(&priority); WPILIB_CheckErrorStatus(status, "GetCurrentThreadPriority"); - *isRealTime = rt; - return ret; + return priority; } -bool SetThreadPriority(std::thread& thread, bool realTime, int priority) { - int32_t status = 0; +bool SetThreadPriority(std::thread& thread, int priority) { auto native = thread.native_handle(); - auto ret = HAL_SetThreadPriority(&native, realTime, priority, &status); + HAL_Status status = HAL_SetThreadPriority(&native, priority); WPILIB_CheckErrorStatus(status, "SetThreadPriority"); - return ret; + return status != 0; } -bool SetCurrentThreadPriority(bool realTime, int priority) { - int32_t status = 0; - auto ret = HAL_SetCurrentThreadPriority(realTime, priority, &status); +bool SetCurrentThreadPriority(int priority) { + HAL_Status status = HAL_SetCurrentThreadPriority(priority); WPILIB_CheckErrorStatus(status, "SetCurrentThreadPriority"); - return ret; + return status != 0; } } // namespace wpi diff --git a/wpilibc/src/main/native/cppcs/RobotBase.cpp b/wpilibc/src/main/native/cppcs/RobotBase.cpp index d5ea33b083..58ae389394 100644 --- a/wpilibc/src/main/native/cppcs/RobotBase.cpp +++ b/wpilibc/src/main/native/cppcs/RobotBase.cpp @@ -24,7 +24,6 @@ #include "wpi/nt/NetworkTableInstance.hpp" #include "wpi/smartdashboard/SmartDashboard.hpp" #include "wpi/system/Errors.hpp" -#include "wpi/system/Notifier.hpp" #include "wpi/system/WPILibVersion.hpp" #include "wpi/util/print.hpp" #include "wpi/util/timestamp.hpp" @@ -51,10 +50,6 @@ int wpi::RunHALInitialization() { HAL_ReportUsage("Language", "C++"); HAL_ReportUsage("WPILibVersion", GetWPILibVersion()); - if (!wpi::Notifier::SetHALThreadPriority(true, 40)) { - WPILIB_ReportWarning("Setting HAL Notifier RT priority to 40 failed\n"); - } - std::puts("\n********** Robot program starting **********"); return 0; } diff --git a/wpilibc/src/main/native/include/wpi/framework/TimesliceRobot.hpp b/wpilibc/src/main/native/include/wpi/framework/TimesliceRobot.hpp index e68904f5ef..21a41c3c8f 100644 --- a/wpilibc/src/main/native/include/wpi/framework/TimesliceRobot.hpp +++ b/wpilibc/src/main/native/include/wpi/framework/TimesliceRobot.hpp @@ -75,7 +75,8 @@ namespace wpi { * If the robot periodic functions and the controller periodic functions have a * lot of scheduling jitter that cause them to occasionally overlap with later * timeslices, consider giving the main robot thread a real-time priority using - * wpi::SetCurrentThreadPriority(). An RT priority of 15 is a reasonable choice. + * wpi::SetCurrentThreadPriority(int). An RT priority of 15 is a reasonable + * choice. * * If you do enable RT though, make sure your periodic functions do not * block. If they do, the operating system will lock up, and you'll have to diff --git a/wpilibc/src/main/native/include/wpi/system/Notifier.hpp b/wpilibc/src/main/native/include/wpi/system/Notifier.hpp index d84b23c02e..169b55750f 100644 --- a/wpilibc/src/main/native/include/wpi/system/Notifier.hpp +++ b/wpilibc/src/main/native/include/wpi/system/Notifier.hpp @@ -36,7 +36,8 @@ class Notifier { * * @param callback The callback to run. */ - explicit Notifier(std::function callback); + explicit Notifier(std::function callback) + : Notifier(0, std::move(callback)) {} template Notifier(std::invocable auto&& callback, Arg&& arg, @@ -140,23 +141,6 @@ class Notifier { */ int32_t GetOverrun() const; - /** - * Sets the HAL notifier thread priority. - * - * The HAL notifier thread is responsible for managing the FPGA's notifier - * interrupt and waking up user's Notifiers when it's their time to run. - * Giving the HAL notifier thread real-time priority helps ensure the user's - * real-time Notifiers, if any, are notified to run in a timely manner. - * - * @param realTime Set to true to set a real-time priority, false for standard - * priority. - * @param priority Priority to set the thread to. For real-time, this is 1-99 - * with 99 being highest. For non-real-time, this is forced to - * 0. See "man 7 sched" for more details. - * @return True on success. - */ - static bool SetHALThreadPriority(bool realTime, int32_t priority); - private: // The thread waiting on the HAL alarm std::thread m_thread; diff --git a/wpilibc/src/main/native/include/wpi/system/Threads.hpp b/wpilibc/src/main/native/include/wpi/system/Threads.hpp index b434a9a401..d758bc347f 100644 --- a/wpilibc/src/main/native/include/wpi/system/Threads.hpp +++ b/wpilibc/src/main/native/include/wpi/system/Threads.hpp @@ -9,49 +9,59 @@ namespace wpi { /** - * Get the thread priority for the specified thread. + * Gets the specified thread's priority. * - * @param thread Reference to the thread to get the priority for. - * @param isRealTime Set to true if thread is real-time, otherwise false. - * @return The current thread priority. For real-time, this is 1-99 - * with 99 being highest. For non-real-time, this is 0. See - * "man 7 sched" for details. + * Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, + * and 99 is highest priority. See "man 7 sched" for details. + * + * @param thread The thread. + * @return The specified thread's priority. */ -int GetThreadPriority(std::thread& thread, bool* isRealTime); +int GetThreadPriority(std::thread& thread); /** - * Get the thread priority for the current thread. + * Gets the current thread's priority. * - * @param isRealTime Set to true if thread is real-time, otherwise false. - * @return The current thread priority. For real-time, this is 1-99 - * with 99 being highest. For non-real-time, this is 0. See - * "man 7 sched" for details. + * Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, + * and 99 is highest priority. See "man 7 sched" for details. + * + * @return The current thread's priority. */ -int GetCurrentThreadPriority(bool* isRealTime); +int GetCurrentThreadPriority(); /** - * Sets the thread priority for the specified thread. + * Sets the specified thread's priority. * - * @param thread Reference to the thread to set the priority of. - * @param realTime Set to true to set a real-time priority, false for standard - * priority. - * @param priority Priority to set the thread to. For real-time, this is 1-99 - * with 99 being highest. For non-real-time, this is forced to - * 0. See "man 7 sched" for more details. - * @return True on success. + * Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, + * and 99 is highest priority. See "man 7 sched" for details. + * + * @param thread The thread. + * @param priority The priority. + * @return True on success. + * @deprecated Incorrect usage of real-time priority can lead to system lockups. + * Only use this function if you are trained in real-time software + * development. */ -bool SetThreadPriority(std::thread& thread, bool realTime, int priority); +[[deprecated( + "Incorrect usage of real-time priority can lead to system lockups. Only " + "use this function if you are trained in real-time software development.")]] +bool SetThreadPriority(std::thread& thread, int priority); /** - * Sets the thread priority for the current thread. + * Sets the current thread's priority. * - * @param realTime Set to true to set a real-time priority, false for standard - * priority. - * @param priority Priority to set the thread to. For real-time, this is 1-99 - * with 99 being highest. For non-real-time, this is forced to - * 0. See "man 7 sched" for more details. - * @return True on success. + * Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, + * and 99 is highest priority. See "man 7 sched" for details. + * + * @param priority The priority. + * @return True on success. + * @deprecated Incorrect usage of real-time priority can lead to system lockups. + * Only use this function if you are trained in real-time software + * development. */ -bool SetCurrentThreadPriority(bool realTime, int priority); +[[deprecated( + "Incorrect usage of real-time priority can lead to system lockups. Only " + "use this function if you are trained in real-time software development.")]] +bool SetCurrentThreadPriority(int priority); } // namespace wpi diff --git a/wpilibc/src/main/python/semiwrap/Notifier.yml b/wpilibc/src/main/python/semiwrap/Notifier.yml index 3f35b07c15..28f4fb2617 100644 --- a/wpilibc/src/main/python/semiwrap/Notifier.yml +++ b/wpilibc/src/main/python/semiwrap/Notifier.yml @@ -19,4 +19,3 @@ classes: wpi::units::second_t: Stop: GetOverrun: - SetHALThreadPriority: diff --git a/wpilibc/src/main/python/wpilib/_impl/start.py b/wpilibc/src/main/python/wpilib/_impl/start.py index 10c6af8086..eba991c0c3 100644 --- a/wpilibc/src/main/python/wpilib/_impl/start.py +++ b/wpilibc/src/main/python/wpilib/_impl/start.py @@ -157,11 +157,6 @@ class RobotStarter: def _start(self, robot_cls: wpilib.RobotBase) -> bool: hal.reportUsage("Language", "Python") - if not wpilib.Notifier.setHALThreadPriority(True, 40): - reportErrorInternal( - "Setting HAL Notifier RT priority to 40 failed", isWarning=True - ) - isSimulation = wpilib.RobotBase.isSimulation() # hack: initialize networktables before creating the robot diff --git a/wpilibc/src/main/python/wpilib/src/rpy/Notifier.cpp b/wpilibc/src/main/python/wpilib/src/rpy/Notifier.cpp index f87728a0c7..1ef0098086 100644 --- a/wpilibc/src/main/python/wpilib/src/rpy/Notifier.cpp +++ b/wpilibc/src/main/python/wpilib/src/rpy/Notifier.cpp @@ -155,8 +155,3 @@ int32_t PyNotifier::GetOverrun() const { WPILIB_CheckErrorStatus(status, "GetNotifierOverrun"); return overrun; } - -bool PyNotifier::SetHALThreadPriority(bool realTime, int32_t priority) { - int32_t status = 0; - return HAL_SetNotifierThreadPriority(realTime, priority, &status); -} diff --git a/wpilibc/src/main/python/wpilib/src/rpy/Notifier.h b/wpilibc/src/main/python/wpilib/src/rpy/Notifier.h index 80e22adc21..d008a819cd 100644 --- a/wpilibc/src/main/python/wpilib/src/rpy/Notifier.h +++ b/wpilibc/src/main/python/wpilib/src/rpy/Notifier.h @@ -101,23 +101,6 @@ class PyNotifier { */ int32_t GetOverrun() const; - /** - * Sets the HAL notifier thread priority. - * - * The HAL notifier thread is responsible for managing the FPGA's notifier - * interrupt and waking up user's Notifiers when it's their time to run. - * Giving the HAL notifier thread real-time priority helps ensure the user's - * real-time Notifiers, if any, are notified to run in a timely manner. - * - * @param realTime Set to true to set a real-time priority, false for standard - * priority. - * @param priority Priority to set the thread to. For real-time, this is 1-99 - * with 99 being highest. For non-real-time, this is forced to - * 0. See "man 7 sched" for more details. - * @return True on success. - */ - static bool SetHALThreadPriority(bool realTime, int32_t priority); - private: // The thread waiting on the HAL alarm py::object m_thread; diff --git a/wpilibj/src/main/java/org/wpilib/framework/RobotBase.java b/wpilibj/src/main/java/org/wpilib/framework/RobotBase.java index b4bb63fb52..ea66f5d094 100644 --- a/wpilibj/src/main/java/org/wpilib/framework/RobotBase.java +++ b/wpilibj/src/main/java/org/wpilib/framework/RobotBase.java @@ -16,7 +16,6 @@ import org.wpilib.math.util.MathSharedStore; import org.wpilib.networktables.MultiSubscriber; import org.wpilib.networktables.NetworkTableEvent; import org.wpilib.networktables.NetworkTableInstance; -import org.wpilib.system.Notifier; import org.wpilib.system.RuntimeType; import org.wpilib.system.Timer; import org.wpilib.system.WPILibVersion; @@ -413,10 +412,6 @@ public abstract class RobotBase implements AutoCloseable { HAL.reportUsage("Language", "Java"); HAL.reportUsage("WPILibVersion", WPILibVersion.Version); - if (!Notifier.setHALThreadPriority(true, 40)) { - DriverStation.reportWarning("Setting HAL Notifier RT priority to 40 failed", false); - } - if (HAL.hasMain()) { Thread thread = new Thread( diff --git a/wpilibj/src/main/java/org/wpilib/framework/TimesliceRobot.java b/wpilibj/src/main/java/org/wpilib/framework/TimesliceRobot.java index 3644356972..4d98400468 100644 --- a/wpilibj/src/main/java/org/wpilib/framework/TimesliceRobot.java +++ b/wpilibj/src/main/java/org/wpilib/framework/TimesliceRobot.java @@ -64,8 +64,8 @@ package org.wpilib.framework; *

If the robot periodic functions and the controller periodic functions have a lot of scheduling * jitter that cause them to occasionally overlap with later timeslices, consider giving the main * robot thread a real-time priority using {@link - * org.wpilib.system.Threads#setCurrentThreadPriority(boolean,int)}. An RT priority of 15 is a - * reasonable choice. + * org.wpilib.system.Threads#setCurrentThreadPriority(int)}. An RT priority of 15 is a reasonable + * choice. * *

If you do enable RT though, make sure your periodic functions do not block. If they do, * the operating system will lock up, and you'll have to boot the roboRIO into safe mode and delete diff --git a/wpilibj/src/main/java/org/wpilib/system/Notifier.java b/wpilibj/src/main/java/org/wpilib/system/Notifier.java index 8b661030dd..9f8cd4c030 100644 --- a/wpilibj/src/main/java/org/wpilib/system/Notifier.java +++ b/wpilibj/src/main/java/org/wpilib/system/Notifier.java @@ -209,21 +209,4 @@ public class Notifier implements AutoCloseable { public void stop() { NotifierJNI.cancelNotifierAlarm(m_notifier.get(), false); } - - /** - * Sets the HAL notifier thread priority. - * - *

The HAL notifier thread is responsible for managing the FPGA's notifier interrupt and waking - * up user's Notifiers when it's their time to run. Giving the HAL notifier thread real-time - * priority helps ensure the user's real-time Notifiers, if any, are notified to run in a timely - * manner. - * - * @param realTime Set to true to set a real-time priority, false for standard priority. - * @param priority Priority to set the thread to. For real-time, this is 1-99 with 99 being - * highest. For non-real-time, this is forced to 0. See "man 7 sched" for more details. - * @return True on success. - */ - public static boolean setHALThreadPriority(boolean realTime, int priority) { - return NotifierJNI.setHALThreadPriority(realTime, priority); - } } diff --git a/wpilibj/src/main/java/org/wpilib/system/Threads.java b/wpilibj/src/main/java/org/wpilib/system/Threads.java index cad90e7d8b..ca0c70aa7f 100644 --- a/wpilibj/src/main/java/org/wpilib/system/Threads.java +++ b/wpilibj/src/main/java/org/wpilib/system/Threads.java @@ -9,34 +9,31 @@ import org.wpilib.hardware.hal.ThreadsJNI; /** Thread utility functions. */ public final class Threads { /** - * Get the thread priority for the current thread. + * Gets the current thread's priority. * - * @return The current thread priority. For real-time, this is 1-99 with 99 being highest. For - * non-real-time, this is 0. See "man 7 sched" for details. + *

Priorities range from 0 to 99 where 0 is non-real-time, and 1-99 are real-time, and 99 is + * highest priority. See "man 7 sched" for details. + * + * @return The current thread's priority. */ public static int getCurrentThreadPriority() { return ThreadsJNI.getCurrentThreadPriority(); } /** - * Get if the current thread is real-time. + * Sets the current thread's priority. * - * @return If the current thread is real-time. - */ - public static boolean getCurrentThreadIsRealTime() { - return ThreadsJNI.getCurrentThreadIsRealTime(); - } - - /** - * Sets the thread priority for the current thread. + *

Priorities range from 0 to 99 where 0 is non-real-time, 1-99 are real-time, and 99 is + * highest priority. See "man 7 sched" for details. * - * @param realTime Set to true to set a real-time priority, false for standard priority. - * @param priority Priority to set the thread to. For real-time, this is 1-99 with 99 being - * highest. For non-real-time, this is forced to 0. See "man 7 sched" for details. + * @param priority The priority. * @return True on success. + * @deprecated Incorrect usage of real-time priority can lead to system lockups. Only use this + * function if you are trained in real-time software development. */ - public static boolean setCurrentThreadPriority(boolean realTime, int priority) { - return ThreadsJNI.setCurrentThreadPriority(realTime, priority); + @Deprecated + public static boolean setCurrentThreadPriority(int priority) { + return ThreadsJNI.setCurrentThreadPriority(priority); } private Threads() {}