WPILibC++ 2026.2.1
Loading...
Searching...
No Matches
Notifier.h
Go to the documentation of this file.
1// 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.
4
5#pragma once
6
7#include <stdint.h>
8
9#include <atomic>
10#include <concepts>
11#include <functional>
12#include <string_view>
13#include <thread>
14#include <utility>
15
16#include <hal/Types.h>
17#include <units/frequency.h>
18#include <units/time.h>
19#include <wpi/mutex.h>
20
21namespace frc {
22
23/**
24 * Notifiers run a user-provided callback function on a separate thread.
25 *
26 * If StartSingle() is used, the callback will run once. If StartPeriodic() is
27 * used, the callback will run repeatedly with the given period until stop() is
28 * called.
29 */
30class Notifier {
31 public:
32 /**
33 * Create a Notifier with the given callback.
34 *
35 * Configure when the callback runs with StartSingle() or StartPeriodic().
36 *
37 * @param callback The callback to run.
38 */
39 explicit Notifier(std::function<void()> callback);
40
41 template <typename Arg, typename... Args>
42 Notifier(std::invocable<Arg, Args...> auto&& callback, Arg&& arg,
43 Args&&... args)
44 : Notifier(std::bind(std::forward<decltype(callback)>(callback),
45 std::forward<Arg>(arg),
46 std::forward<Args>(args)...)) {}
47
48 /**
49 * Create a Notifier with the given callback.
50 *
51 * Configure when the callback runs with StartSingle() or StartPeriodic().
52 *
53 * This overload makes the underlying thread run with a real-time priority.
54 * This is useful for reducing scheduling jitter on processes which are
55 * sensitive to timing variance, like model-based control.
56 *
57 * @param priority The FIFO real-time scheduler priority ([1..99] where a
58 * higher number represents higher priority). See "man 7
59 * sched" for more details.
60 * @param callback The callback to run.
61 */
62 explicit Notifier(int priority, std::function<void()> callback);
63
64 template <typename Arg, typename... Args>
65 Notifier(int priority, std::invocable<Arg, Args...> auto&& callback,
66 Arg&& arg, Args&&... args)
67 : Notifier(priority, std::bind(std::forward<decltype(callback)>(callback),
68 std::forward<Arg>(arg),
69 std::forward<Args>(args)...)) {}
70
71 /**
72 * Free the resources for a timer event.
73 */
75
78
79 /**
80 * Sets the name of the notifier. Used for debugging purposes only.
81 *
82 * @param name Name
83 */
84 void SetName(std::string_view name);
85
86 /**
87 * Change the callback function.
88 *
89 * @param callback The callback function.
90 */
91 void SetCallback(std::function<void()> callback);
92
93 /**
94 * Run the callback once after the given delay.
95 *
96 * @param delay Time to wait before the callback is called.
97 */
98 void StartSingle(units::second_t delay);
99
100 /**
101 * Run the callback periodically with the given period.
102 *
103 * The user-provided callback should be written so that it completes before
104 * the next time it's scheduled to run.
105 *
106 * @param period Period after which to call the callback starting one
107 * period after the call to this method.
108 */
109 void StartPeriodic(units::second_t period);
110
111 /**
112 * Run the callback periodically with the given frequency.
113 *
114 * The user-provided callback should be written so that it completes before
115 * the next time it's scheduled to run.
116 *
117 * @param frequency Frequency after which to call the callback starting one
118 * period after the call to this method.
119 */
120 void StartPeriodic(units::hertz_t frequency);
121
122 /**
123 * Stop further callback invocations.
124 *
125 * No further periodic callbacks will occur. Single invocations will also be
126 * cancelled if they haven't yet occurred.
127 *
128 * If a callback invocation is in progress, this function will block until the
129 * callback is complete.
130 */
131 void Stop();
132
133 /**
134 * Sets the HAL notifier thread priority.
135 *
136 * The HAL notifier thread is responsible for managing the FPGA's notifier
137 * interrupt and waking up user's Notifiers when it's their time to run.
138 * Giving the HAL notifier thread real-time priority helps ensure the user's
139 * real-time Notifiers, if any, are notified to run in a timely manner.
140 *
141 * @param realTime Set to true to set a real-time priority, false for standard
142 * priority.
143 * @param priority Priority to set the thread to. For real-time, this is 1-99
144 * with 99 being highest. For non-real-time, this is forced to
145 * 0. See "man 7 sched" for more details.
146 * @return True on success.
147 */
148 static bool SetHALThreadPriority(bool realTime, int32_t priority);
149
150 private:
151 /**
152 * Update the HAL alarm time.
153 *
154 * @param triggerTime the time at which the next alarm will be triggered
155 */
156 void UpdateAlarm(uint64_t triggerTime);
157
158 /**
159 * Update the HAL alarm time based on m_expirationTime.
160 */
161 void UpdateAlarm();
162
163 // The thread waiting on the HAL alarm
164 std::thread m_thread;
165
166 // The mutex held while updating process information
167 wpi::mutex m_processMutex;
168
169 // HAL handle (atomic for proper destruction)
170 std::atomic<HAL_NotifierHandle> m_notifier{0};
171
172 // The user-provided callback
173 std::function<void()> m_callback;
174
175 // The time at which the callback should be called. Has the same zero as
176 // Timer::GetFPGATimestamp().
177 units::second_t m_expirationTime = 0_s;
178
179 // If periodic, stores the callback period; if single, stores the time until
180 // the callback call.
181 units::second_t m_period = 0_s;
182
183 // True if the callback is periodic
184 bool m_periodic = false;
185};
186
187} // namespace frc
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Returns a named argument to be used in a formatting function.
Definition base.h:2775
Notifiers run a user-provided callback function on a separate thread.
Definition Notifier.h:30
Notifier(std::invocable< Arg, Args... > auto &&callback, Arg &&arg, Args &&... args)
Definition Notifier.h:42
Notifier(Notifier &&rhs)
Notifier(std::function< void()> callback)
Create a Notifier with the given callback.
void StartPeriodic(units::hertz_t frequency)
Run the callback periodically with the given frequency.
void StartPeriodic(units::second_t period)
Run the callback periodically with the given period.
void SetName(std::string_view name)
Sets the name of the notifier.
void Stop()
Stop further callback invocations.
Notifier(int priority, std::function< void()> callback)
Create a Notifier with the given callback.
static bool SetHALThreadPriority(bool realTime, int32_t priority)
Sets the HAL notifier thread priority.
void StartSingle(units::second_t delay)
Run the callback once after the given delay.
void SetCallback(std::function< void()> callback)
Change the callback function.
Notifier(int priority, std::invocable< Arg, Args... > auto &&callback, Arg &&arg, Args &&... args)
Definition Notifier.h:65
~Notifier()
Free the resources for a timer event.
Notifier & operator=(Notifier &&rhs)
Definition CAN.h:11
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
::std::mutex mutex
Definition mutex.h:17