WPILibC++ 2025.3.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/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 */
83 void SetName(std::string_view name);
84
85 /**
86 * Change the callback function.
87 *
88 * @param callback The callback function.
89 */
90 void SetCallback(std::function<void()> callback);
91
92 /**
93 * Run the callback once after the given delay.
94 *
95 * @param delay Time to wait before the callback is called.
96 */
97 void StartSingle(units::second_t delay);
98
99 /**
100 * Run the callback periodically with the given period.
101 *
102 * The user-provided callback should be written so that it completes before
103 * the next time it's scheduled to run.
104 *
105 * @param period Period after which to to call the callback starting one
106 * period after the call to this method.
107 */
108 void StartPeriodic(units::second_t period);
109
110 /**
111 * Stop further callback invocations.
112 *
113 * No further periodic callbacks will occur. Single invocations will also be
114 * cancelled if they haven't yet occurred.
115 *
116 * If a callback invocation is in progress, this function will block until the
117 * callback is complete.
118 */
119 void Stop();
120
121 /**
122 * Sets the HAL notifier thread priority.
123 *
124 * The HAL notifier thread is responsible for managing the FPGA's notifier
125 * interrupt and waking up user's Notifiers when it's their time to run.
126 * Giving the HAL notifier thread real-time priority helps ensure the user's
127 * real-time Notifiers, if any, are notified to run in a timely manner.
128 *
129 * @param realTime Set to true to set a real-time priority, false for standard
130 * priority.
131 * @param priority Priority to set the thread to. For real-time, this is 1-99
132 * with 99 being highest. For non-real-time, this is forced to
133 * 0. See "man 7 sched" for more details.
134 * @return True on success.
135 */
136 static bool SetHALThreadPriority(bool realTime, int32_t priority);
137
138 private:
139 /**
140 * Update the HAL alarm time.
141 *
142 * @param triggerTime the time at which the next alarm will be triggered
143 */
144 void UpdateAlarm(uint64_t triggerTime);
145
146 /**
147 * Update the HAL alarm time based on m_expirationTime.
148 */
149 void UpdateAlarm();
150
151 // The thread waiting on the HAL alarm
152 std::thread m_thread;
153
154 // The mutex held while updating process information
155 wpi::mutex m_processMutex;
156
157 // HAL handle (atomic for proper destruction)
158 std::atomic<HAL_NotifierHandle> m_notifier{0};
159
160 // The user-provided callback
161 std::function<void()> m_callback;
162
163 // The time at which the callback should be called. Has the same zero as
164 // Timer::GetFPGATimestamp().
165 units::second_t m_expirationTime = 0_s;
166
167 // If periodic, stores the callback period; if single, stores the time until
168 // the callback call.
169 units::second_t m_period = 0_s;
170
171 // True if the callback is periodic
172 bool m_periodic = false;
173};
174
175} // 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)
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
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