19
19
#define __MBED_UTIL_CRITICAL_H__
20
20
21
21
#include <stdbool.h>
22
+ #include <stdint.h>
23
+ #include <stddef.h>
22
24
23
25
#ifdef __cplusplus
24
26
extern "C" {
@@ -47,7 +49,7 @@ bool core_util_are_interrupts_enabled(void);
47
49
* section) will be preserved on exit from the section.
48
50
* 4) This implementation will currently only work on code running in privileged mode.
49
51
*/
50
- void core_util_critical_section_enter ();
52
+ void core_util_critical_section_enter (void );
51
53
52
54
/** Mark the end of a critical section
53
55
*
@@ -60,7 +62,7 @@ void core_util_critical_section_enter();
60
62
* section) will be preserved on exit from the section.
61
63
* 4) This implementation will currently only work on code running in privileged mode.
62
64
*/
63
- void core_util_critical_section_exit ();
65
+ void core_util_critical_section_exit (void );
64
66
65
67
/**
66
68
* Atomic compare and set. It compares the contents of a memory location to a
@@ -106,7 +108,7 @@ void core_util_critical_section_exit();
106
108
*
107
109
* function incr(p : pointer to int, a : int) returns int {
108
110
* done = false
109
- * * value = *p // This fetch operation need not be atomic.
111
+ * value = *p // This fetch operation need not be atomic.
110
112
* while not done {
111
113
* done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
112
114
* }
@@ -159,7 +161,7 @@ bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_
159
161
*
160
162
* function incr(p : pointer to int, a : int) returns int {
161
163
* done = false
162
- * * value = *p // This fetch operation need not be atomic.
164
+ * value = *p // This fetch operation need not be atomic.
163
165
* while not done {
164
166
* done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
165
167
* }
@@ -212,7 +214,7 @@ bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uin
212
214
*
213
215
* function incr(p : pointer to int, a : int) returns int {
214
216
* done = false
215
- * * value = *p // This fetch operation need not be atomic.
217
+ * value = *p // This fetch operation need not be atomic.
216
218
* while not done {
217
219
* done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
218
220
* }
@@ -221,53 +223,128 @@ bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uin
221
223
*/
222
224
bool core_util_atomic_cas_u32 (uint32_t * ptr , uint32_t * expectedCurrentValue , uint32_t desiredValue );
223
225
226
+ /**
227
+ * Atomic compare and set. It compares the contents of a memory location to a
228
+ * given value and, only if they are the same, modifies the contents of that
229
+ * memory location to a given new value. This is done as a single atomic
230
+ * operation. The atomicity guarantees that the new value is calculated based on
231
+ * up-to-date information; if the value had been updated by another thread in
232
+ * the meantime, the write would fail due to a mismatched expectedCurrentValue.
233
+ *
234
+ * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect
235
+ * you to the article on compare-and swap].
236
+ *
237
+ * @param ptr The target memory location.
238
+ * @param[in,out] expectedCurrentValue A pointer to some location holding the
239
+ * expected current value of the data being set atomically.
240
+ * The computed 'desiredValue' should be a function of this current value.
241
+ * @Note: This is an in-out parameter. In the
242
+ * failure case of atomic_cas (where the
243
+ * destination isn't set), the pointee of expectedCurrentValue is
244
+ * updated with the current value.
245
+ * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'.
246
+ *
247
+ * @return true if the memory location was atomically
248
+ * updated with the desired value (after verifying
249
+ * that it contained the expectedCurrentValue),
250
+ * false otherwise. In the failure case,
251
+ * exepctedCurrentValue is updated with the new
252
+ * value of the target memory location.
253
+ *
254
+ * pseudocode:
255
+ * function cas(p : pointer to int, old : pointer to int, new : int) returns bool {
256
+ * if *p != *old {
257
+ * *old = *p
258
+ * return false
259
+ * }
260
+ * *p = new
261
+ * return true
262
+ * }
263
+ *
264
+ * @Note: In the failure case (where the destination isn't set), the value
265
+ * pointed to by expectedCurrentValue is still updated with the current value.
266
+ * This property helps writing concise code for the following incr:
267
+ *
268
+ * function incr(p : pointer to int, a : int) returns int {
269
+ * done = false
270
+ * value = *p // This fetch operation need not be atomic.
271
+ * while not done {
272
+ * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
273
+ * }
274
+ * return value + a
275
+ * }
276
+ */
277
+ bool core_util_atomic_cas_ptr (void * * ptr , void * * expectedCurrentValue , void * desiredValue );
278
+
224
279
/**
225
280
* Atomic increment.
226
281
* @param valuePtr Target memory location being incremented.
227
282
* @param delta The amount being incremented.
228
283
* @return The new incremented value.
229
284
*/
230
- uint8_t core_util_atomic_incr_u8 (uint8_t * valuePtr , uint8_t delta );
285
+ uint8_t core_util_atomic_incr_u8 (uint8_t * valuePtr , uint8_t delta );
231
286
232
287
/**
233
288
* Atomic increment.
234
289
* @param valuePtr Target memory location being incremented.
235
290
* @param delta The amount being incremented.
236
291
* @return The new incremented value.
237
292
*/
238
- uint16_t core_util_atomic_incr_u16 (uint16_t * valuePtr , uint16_t delta );
293
+ uint16_t core_util_atomic_incr_u16 (uint16_t * valuePtr , uint16_t delta );
239
294
240
295
/**
241
296
* Atomic increment.
242
297
* @param valuePtr Target memory location being incremented.
243
298
* @param delta The amount being incremented.
244
299
* @return The new incremented value.
245
300
*/
246
- uint32_t core_util_atomic_incr_u32 (uint32_t * valuePtr , uint32_t delta );
301
+ uint32_t core_util_atomic_incr_u32 (uint32_t * valuePtr , uint32_t delta );
302
+
303
+ /**
304
+ * Atomic increment.
305
+ * @param valuePtr Target memory location being incremented.
306
+ * @param delta The amount being incremented in bytes.
307
+ * @return The new incremented value.
308
+ *
309
+ * @note The type of the pointer argument is not taken into account
310
+ * and the pointer is incremented by bytes.
311
+ */
312
+ void * core_util_atomic_incr_ptr (void * * valuePtr , ptrdiff_t delta );
247
313
248
314
/**
249
315
* Atomic decrement.
250
316
* @param valuePtr Target memory location being decremented.
251
317
* @param delta The amount being decremented.
252
318
* @return The new decremented value.
253
319
*/
254
- uint8_t core_util_atomic_decr_u8 (uint8_t * valuePtr , uint8_t delta );
320
+ uint8_t core_util_atomic_decr_u8 (uint8_t * valuePtr , uint8_t delta );
255
321
256
322
/**
257
323
* Atomic decrement.
258
324
* @param valuePtr Target memory location being decremented.
259
325
* @param delta The amount being decremented.
260
326
* @return The new decremented value.
261
327
*/
262
- uint16_t core_util_atomic_decr_u16 (uint16_t * valuePtr , uint16_t delta );
328
+ uint16_t core_util_atomic_decr_u16 (uint16_t * valuePtr , uint16_t delta );
263
329
264
330
/**
265
331
* Atomic decrement.
266
332
* @param valuePtr Target memory location being decremented.
267
333
* @param delta The amount being decremented.
268
334
* @return The new decremented value.
269
335
*/
270
- uint32_t core_util_atomic_decr_u32 (uint32_t * valuePtr , uint32_t delta );
336
+ uint32_t core_util_atomic_decr_u32 (uint32_t * valuePtr , uint32_t delta );
337
+
338
+ /**
339
+ * Atomic decrement.
340
+ * @param valuePtr Target memory location being decremented.
341
+ * @param delta The amount being decremented in bytes.
342
+ * @return The new decremented value.
343
+ *
344
+ * @note The type of the pointer argument is not taken into account
345
+ * and the pointer is decremented by bytes
346
+ */
347
+ void * core_util_atomic_decr_ptr (void * * valuePtr , ptrdiff_t delta );
271
348
272
349
#ifdef __cplusplus
273
350
} // extern "C"
0 commit comments