@@ -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 */
381402void __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