Skip to content

Commit 250758c

Browse files
authored
Merge pull request #21883 from maribu/core/lib/atomics
core/lib/atomic_c11: Add __atomic_test_and_set()
2 parents 0800547 + a32e108 commit 250758c

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

core/lib/atomic_c11.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,6 @@ TEMPLATE_ATOMIC_OP_FETCH_N(nand, &, 8, ~) /* __atomic_nand_fetch_8 */
261261

262262
/* ***** Generic versions below ***** */
263263

264-
/* Clang objects if you redefine a builtin. This little hack allows us to
265-
* define a function with the same name as an intrinsic. */
266-
/* Hack origin: http://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/builtins/atomic.c */
267-
#pragma redefine_extname __atomic_load_c __atomic_load
268-
#pragma redefine_extname __atomic_store_c __atomic_store
269-
#pragma redefine_extname __atomic_exchange_c __atomic_exchange
270-
#pragma redefine_extname __atomic_compare_exchange_c __atomic_compare_exchange
271-
272264
/**
273265
* @brief Atomic generic load
274266
*
@@ -376,6 +368,35 @@ bool __atomic_compare_exchange_c(size_t len, void *ptr, void *expected,
376368
irq_restore(mask);
377369
return ret;
378370
}
371+
372+
/**
373+
* This built-in function performs an atomic test-and-set operation on the byte
374+
* at *ptr. The byte is set to some implementation defined nonzero “set” value
375+
* and the return value is true if and only if the previous contents were “set”.
376+
* It should be only used for operands of type bool.
377+
*
378+
* All memory orders are valid.
379+
*
380+
* @see https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html#index-_005f_005fatomic_005ftest_005fand_005fset
381+
*
382+
* @param[in,out] ptr Value to test and then set
383+
* @param[in] memorder Ignored
384+
*
385+
* @retval true The value @p ptr was already set
386+
* @retval false The value @p ptr was previously unset
387+
*
388+
* @pre @p ptr points to a value of `bool`
389+
*/
390+
bool __atomic_test_and_set_c(void *ptr, int memorder)
391+
{
392+
(void)memorder;
393+
bool *target = ptr;
394+
unsigned mask = irq_disable();
395+
bool retval = *target;
396+
*target = true;
397+
irq_restore(mask);
398+
return retval;
399+
}
379400
#if !defined(__llvm__) && !defined(__clang__)
380401
/* Memory barrier helper function, for platforms without barrier instructions */
381402
void __sync_synchronize(void) __attribute__((__weak__));
@@ -389,4 +410,15 @@ void __sync_synchronize(void)
389410
__asm__ volatile ("" : : : "memory");
390411
}
391412
#endif
413+
414+
/* Clang objects if you redefine a builtin. This little hack allows us to
415+
* define a function with the same name as an intrinsic. */
416+
/* Hack origin: http://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/builtins/atomic.c */
417+
/* Note: The rename must come *after* the declaration of the symbol to work in
418+
* GCC. */
419+
#pragma redefine_extname __atomic_load_c __atomic_load
420+
#pragma redefine_extname __atomic_store_c __atomic_store
421+
#pragma redefine_extname __atomic_exchange_c __atomic_exchange
422+
#pragma redefine_extname __atomic_compare_exchange_c __atomic_compare_exchange
423+
#pragma redefine_extname __atomic_test_and_set_c __atomic_test_and_set
392424
/** @} */

0 commit comments

Comments
 (0)