[hal] Set HAL Notifier thread as RT by default (#3482)

This PR gives the Notifier HAL thread RT priority 40 in RobotBase after
HAL initialization and before the user code is run. This drastically
improves scheduling jitter for TimedRobot's AddPeriodic() functions (in
3512's experience).

It's too risky to set user code as RT because badly behaved code
will lock up the Rio (potentially requiring safe mode to recover).

This needs the user program to be setuid admin to succeed.
This commit is contained in:
Tyler Veness
2021-08-14 11:42:35 -07:00
committed by GitHub
parent 192d251ee8
commit 5d9ae3cdb4
8 changed files with 182 additions and 14 deletions

View File

@@ -0,0 +1,68 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include <thread>
#include <wpi/condition_variable.h>
#include <wpi/mutex.h>
#include "frc/Threads.h"
#include "gtest/gtest.h"
TEST(PriorityTest, SetThreadPriority) {
bool exited = false;
wpi::condition_variable cond;
wpi::mutex mutex;
std::thread thr{[&] {
std::unique_lock lock{mutex};
cond.wait(lock, [&] { return exited; });
}};
// Non-RT thread has priority of zero
bool isRealTime = false;
EXPECT_EQ(0, frc::GetThreadPriority(thr, &isRealTime));
EXPECT_FALSE(isRealTime);
// Set thread priority to 15
EXPECT_TRUE(frc::SetThreadPriority(thr, true, 15));
// Verify thread was given priority 15
EXPECT_EQ(15, frc::GetThreadPriority(thr, &isRealTime));
EXPECT_TRUE(isRealTime);
// Set thread back to non-RT
EXPECT_TRUE(frc::SetThreadPriority(thr, false, 0));
// Verify thread is now non-RT
EXPECT_EQ(0, frc::GetThreadPriority(thr, &isRealTime));
EXPECT_FALSE(isRealTime);
{
std::scoped_lock lock{mutex};
exited = true;
}
cond.notify_one();
thr.join();
}
TEST(PriorityTest, SetCurrentThreadPriority) {
// Non-RT thread has priority of zero
bool isRealTime = true;
EXPECT_EQ(0, frc::GetCurrentThreadPriority(&isRealTime));
EXPECT_FALSE(isRealTime);
// Set thread priority to 15
EXPECT_TRUE(frc::SetCurrentThreadPriority(true, 15));
// Verify thread was given priority 15
EXPECT_EQ(15, frc::GetCurrentThreadPriority(&isRealTime));
EXPECT_TRUE(isRealTime);
// Set thread back to non-RT
EXPECT_TRUE(frc::SetCurrentThreadPriority(false, 0));
// Verify thread is now non-RT
EXPECT_EQ(0, frc::GetCurrentThreadPriority(&isRealTime));
EXPECT_FALSE(isRealTime);
}