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