@@ -221,6 +221,59 @@ bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uin
221
221
*/
222
222
bool core_util_atomic_cas_u32 (uint32_t * ptr , uint32_t * expectedCurrentValue , uint32_t desiredValue );
223
223
224
+ /**
225
+ * Atomic compare and set. It compares the contents of a memory location to a
226
+ * given value and, only if they are the same, modifies the contents of that
227
+ * memory location to a given new value. This is done as a single atomic
228
+ * operation. The atomicity guarantees that the new value is calculated based on
229
+ * up-to-date information; if the value had been updated by another thread in
230
+ * the meantime, the write would fail due to a mismatched expectedCurrentValue.
231
+ *
232
+ * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect
233
+ * you to the article on compare-and swap].
234
+ *
235
+ * @param ptr The target memory location.
236
+ * @param[in,out] expectedCurrentValue A pointer to some location holding the
237
+ * expected current value of the data being set atomically.
238
+ * The computed 'desiredValue' should be a function of this current value.
239
+ * @Note: This is an in-out parameter. In the
240
+ * failure case of atomic_cas (where the
241
+ * destination isn't set), the pointee of expectedCurrentValue is
242
+ * updated with the current value.
243
+ * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'.
244
+ *
245
+ * @return true if the memory location was atomically
246
+ * updated with the desired value (after verifying
247
+ * that it contained the expectedCurrentValue),
248
+ * false otherwise. In the failure case,
249
+ * exepctedCurrentValue is updated with the new
250
+ * value of the target memory location.
251
+ *
252
+ * pseudocode:
253
+ * function cas(p : pointer to int, old : pointer to int, new : int) returns bool {
254
+ * if *p != *old {
255
+ * *old = *p
256
+ * return false
257
+ * }
258
+ * *p = new
259
+ * return true
260
+ * }
261
+ *
262
+ * @Note: In the failure case (where the destination isn't set), the value
263
+ * pointed to by expectedCurrentValue is still updated with the current value.
264
+ * This property helps writing concise code for the following incr:
265
+ *
266
+ * function incr(p : pointer to int, a : int) returns int {
267
+ * done = false
268
+ * *value = *p // This fetch operation need not be atomic.
269
+ * while not done {
270
+ * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
271
+ * }
272
+ * return value + a
273
+ * }
274
+ */
275
+ bool core_util_atomic_cas_ptr (void * * ptr , void * * expectedCurrentValue , void * desiredValue );
276
+
224
277
/**
225
278
* Atomic increment.
226
279
* @param valuePtr Target memory location being incremented.
@@ -245,6 +298,14 @@ uint16_t core_util_atomic_incr_u16(uint16_t * valuePtr, uint16_t delta);
245
298
*/
246
299
uint32_t core_util_atomic_incr_u32 (uint32_t * valuePtr , uint32_t delta );
247
300
301
+ /**
302
+ * Atomic increment.
303
+ * @param valuePtr Target memory location being incremented.
304
+ * @param delta The amount being incremented.
305
+ * @return The new incremented value.
306
+ */
307
+ void * core_util_atomic_incr_ptr (void * * valuePtr , unsigned delta );
308
+
248
309
/**
249
310
* Atomic decrement.
250
311
* @param valuePtr Target memory location being decremented.
@@ -269,6 +330,14 @@ uint16_t core_util_atomic_decr_u16(uint16_t * valuePtr, uint16_t delta);
269
330
*/
270
331
uint32_t core_util_atomic_decr_u32 (uint32_t * valuePtr , uint32_t delta );
271
332
333
+ /**
334
+ * Atomic decrement.
335
+ * @param valuePtr Target memory location being decremented.
336
+ * @param delta The amount being decremented.
337
+ * @return The new decremented value.
338
+ */
339
+ void * core_util_atomic_decr_ptr (void * * valuePtr , unsigned delta );
340
+
272
341
#ifdef __cplusplus
273
342
} // extern "C"
274
343
#endif
0 commit comments