0c402157fc8f586e443468e61ca94ce01a9a0ea4
- Author
- Nick Brassel <nick@tzarc.org>
- Committer
- GitHub <noreply@github.com>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/quantum/deferred_exec.c b/quantum/deferred_exec.c
2index 5b0a5b14258b0129d17be9599f49c748cde906ff..a64b451df2d2c691d490c7d0a7d398430daaa83e 100644
3--- a/quantum/deferred_exec.c
4+++ b/quantum/deferred_exec.c
5@@ -9,32 +9,27 @@
6 # define MAX_DEFERRED_EXECUTORS 8
7 #endif
8
9-typedef struct deferred_executor_t {
10- deferred_token token;
11- uint32_t trigger_time;
12- deferred_exec_callback callback;
13- void * cb_arg;
14-} deferred_executor_t;
15-
16-static deferred_token current_token = 0;
17-static uint32_t last_deferred_exec_check = 0;
18-static deferred_executor_t executors[MAX_DEFERRED_EXECUTORS] = {0};
19-
20-static inline bool token_can_be_used(deferred_token token) {
21+//------------------------------------
22+// Helpers
23+//
24+
25+static deferred_token current_token = 0;
26+
27+static inline bool token_can_be_used(deferred_executor_t *table, size_t table_count, deferred_token token) {
28 if (token == INVALID_DEFERRED_TOKEN) {
29 return false;
30 }
31- for (int i = 0; i < MAX_DEFERRED_EXECUTORS; ++i) {
32- if (executors[i].token == token) {
33+ for (int i = 0; i < table_count; ++i) {
34+ if (table[i].token == token) {
35 return false;
36 }
37 }
38 return true;
39 }
40
41-static inline deferred_token allocate_token(void) {
42+static inline deferred_token allocate_token(deferred_executor_t *table, size_t table_count) {
43 deferred_token first = ++current_token;
44- while (!token_can_be_used(current_token)) {
45+ while (!token_can_be_used(table, table_count, current_token)) {
46 ++current_token;
47 if (current_token == first) {
48 // If we've looped back around to the first, everything is already allocated (yikes!). Need to exit with a failure.
49@@ -44,18 +39,22 @@ static inline deferred_token allocate_token(void) {
50 return current_token;
51 }
52
53-deferred_token defer_exec(uint32_t delay_ms, deferred_exec_callback callback, void *cb_arg) {
54- // Ignore queueing if it's a zero-time delay, or invalid callback
55- if (delay_ms == 0 || !callback) {
56+//------------------------------------
57+// Advanced API: used when a custom-allocated table is used, primarily for core code.
58+//
59+
60+deferred_token defer_exec_advanced(deferred_executor_t *table, size_t table_count, uint32_t delay_ms, deferred_exec_callback callback, void *cb_arg) {
61+ // Ignore queueing if the table isn't valid, it's a zero-time delay, or the token is not valid
62+ if (!table || table_count == 0 || delay_ms == 0 || !callback) {
63 return INVALID_DEFERRED_TOKEN;
64 }
65
66 // Find an unused slot and claim it
67- for (int i = 0; i < MAX_DEFERRED_EXECUTORS; ++i) {
68- deferred_executor_t *entry = &executors[i];
69+ for (int i = 0; i < table_count; ++i) {
70+ deferred_executor_t *entry = &table[i];
71 if (entry->token == INVALID_DEFERRED_TOKEN) {
72 // Work out the new token value, dropping out if none were available
73- deferred_token token = allocate_token();
74+ deferred_token token = allocate_token(table, table_count);
75 if (token == INVALID_DEFERRED_TOKEN) {
76 return false;
77 }
78@@ -73,15 +72,15 @@ deferred_token defer_exec(uint32_t delay_ms, deferred_exec_callback callback, vo
79 return INVALID_DEFERRED_TOKEN;
80 }
81
82-bool extend_deferred_exec(deferred_token token, uint32_t delay_ms) {
83- // Ignore queueing if it's a zero-time delay, or the token is not valid
84- if (delay_ms == 0 || token == INVALID_DEFERRED_TOKEN) {
85+bool extend_deferred_exec_advanced(deferred_executor_t *table, size_t table_count, deferred_token token, uint32_t delay_ms) {
86+ // Ignore queueing if the table isn't valid, it's a zero-time delay, or the token is not valid
87+ if (!table || table_count == 0 || delay_ms == 0 || token == INVALID_DEFERRED_TOKEN) {
88 return false;
89 }
90
91 // Find the entry corresponding to the token
92- for (int i = 0; i < MAX_DEFERRED_EXECUTORS; ++i) {
93- deferred_executor_t *entry = &executors[i];
94+ for (int i = 0; i < table_count; ++i) {
95+ deferred_executor_t *entry = &table[i];
96 if (entry->token == token) {
97 // Found it, extend the delay
98 entry->trigger_time = timer_read32() + delay_ms;
99@@ -93,15 +92,15 @@ bool extend_deferred_exec(deferred_token token, uint32_t delay_ms) {
100 return false;
101 }
102
103-bool cancel_deferred_exec(deferred_token token) {
104- // Ignore request if the token is not valid
105diff --git a/quantum/deferred_exec.h b/quantum/deferred_exec.h
106index f80d353169bf22d86a6c3d2dd7040a32202415db..97ef0f6c0e2b40e1e7a564b0dec534cd79a575df 100644
107--- a/quantum/deferred_exec.h
108+++ b/quantum/deferred_exec.h
109@@ -5,34 +5,117 @@
110
111 #include <stdbool.h>
112 #include <stdint.h>
113+#include <stdlib.h>
114
115-// A token that can be used to cancel an existing deferred execution.
116+//------------------------------------
117+// Common
118+//------------------------------------
119+
120+/**
121+ * @typedef A token that can be used to cancel or extend an existing deferred execution.
122+ */
123 typedef uint8_t deferred_token;
124+
125+/**
126+ * @def The constant used to denote an invalid deferred execution token.
127+ */
128 #define INVALID_DEFERRED_TOKEN 0
129
130-// Callback to execute.
131-// -- Parameter trigger_time: the intended trigger time to execute the callback -- equivalent time-space as timer_read32()
132-// cb_arg: the callback argument specified when enqueueing the deferred executor
133-// -- Return value: Non-zero re-queues the callback to execute after the returned number of milliseconds. Zero cancels repeated execution.
134+/**
135+ * @typedef Callback to execute.
136+ * @param trigger_time[in] the intended trigger time to execute the callback -- equivalent time-space as timer_read32()
137+ * @param cb_arg[in] the callback argument specified when enqueueing the deferred executor
138+ * @return non-zero re-queues the callback to execute after the returned number of milliseconds. Zero cancels repeated execution.
139+ */
140 typedef uint32_t (*deferred_exec_callback)(uint32_t trigger_time, void *cb_arg);
141
142-// Configures the supplied deferred executor to be executed after the required number of milliseconds.
143-// -- Parameter delay_ms: the number of milliseconds before executing the callback
144-// -- callback: the executor to invoke
145-// -- cb_arg: the argument to pass to the executor, may be NULL if unused by the executor
146-// -- Return value: a token usable for cancellation, or INVALID_DEFERRED_TOKEN if an error occurred
147+//------------------------------------
148+// Basic API: used by user-mode code, guaranteed to not collide with core deferred execution
149+//------------------------------------
150+
151+/**
152+ * Configures the supplied deferred executor to be executed after the required number of milliseconds.
153+ *
154+ * @param delay_ms[in] the number of milliseconds before executing the callback
155+ * @param callback[in] the executor to invoke
156+ * @param cb_arg[in] the argument to pass to the executor, may be NULL if unused by the executor
157+ * @return a token usable for extension/cancellation, or INVALID_DEFERRED_TOKEN if an error occurred
158+ */
159 deferred_token defer_exec(uint32_t delay_ms, deferred_exec_callback callback, void *cb_arg);
160
161-// Allows for extending the timeframe before an existing deferred execution is invoked.
162-// -- Parameter token: the returned value from defer_exec for the deferred execution you wish to extend.
163-// -- delay_ms: the new delay (with respect to the current time)
164-// -- Return value: if the token was found, and the delay was extended
165+/**
166+ * Allows for extending the timeframe before an existing deferred execution is invoked.
167+ *
168+ * @param token[in] the returned value from defer_exec for the deferred execution you wish to extend
169+ * @param delay_ms[in] the number of milliseconds before executing the callback
170+ * @return true if the token was extended successfully, otherwise false
171+ */
172 bool extend_deferred_exec(deferred_token token, uint32_t delay_ms);
173
174-// Allows for cancellation of an existing deferred execution.
175-// -- Parameter token: the returned value from defer_exec for the deferred execution you wish to cancel.
176-// -- Return value: if the token was found, and the executor was cancelled
177+/**
178+ * Allows for cancellation of an existing deferred execution.
179+ *
180+ * @param token[in] the returned value from defer_exec for the deferred execution you wish to cancel
181+ * @return true if the token was cancelled successfully, otherwise false
182+ */
183 bool cancel_deferred_exec(deferred_token token);
184
185-// Forward declaration for the main loop in order to execute any deferred executors. Should not be invoked by keyboard/user code.
186+/**
187+ * Forward declaration for the main loop in order to execute any deferred executors. Should not be invoked by keyboard/user code.
188+ */
189 void deferred_exec_task(void);
190+
191+//------------------------------------
192+// Advanced API: used when a custom-allocated table is used, primarily for core code.
193+//------------------------------------
194+
195+/**
196+ * @struct Structure for containing self-hosted deferred executor tables.
197+ * @brief Core-side code can use this to create their own tables without impacting on the use of users' ability to add deferred execution.
198+ * Code outside deferred_exec.c should not worry about internals of this struct, and should just allocate the required number in an array.
199+ */
200+typedef struct deferred_executor_t {
201+ deferred_token token;
202+ uint32_t trigger_time;
203+ deferred_exec_callback callback;
204+ void * cb_arg;
205+} deferred_executor_t;
206+
207+/**
208+ * Configures the supplied deferred executor to be executed after the required number of milliseconds.