[libcxx-commits] [PATCH] D65348: enable <atomic> header on systems without thread-support

Yves Delley via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jul 26 13:46:28 PDT 2019


burnpanck created this revision.
burnpanck added a reviewer: libc++.
Herald added subscribers: libcxx-commits, jfb, ldionne, christof, kristof.beyls, javed.absar.

This patch enables the `<atomic>` header on systems without thread support, such as for example ARMv7em baremetal targets.
It consists essentially of three changes:

1. Do not blindly refuse <atomic> when _LIBCPP_HAS_NO_THREADS is defined. I removed corresponding `#error` at the top of `<atomic>`. Furthermore, I changed the logic in `<__config>` where _LIBCPP_HAS_NO_ATOMIC_HEADER is determined to ignore _LIBCPP_HAS_NO_THREADS.
2. In `<__config>`, define _LIBCPP_ATOMIC_ONLY_USE_BUILTINS when _LIBCPP_HAS_NO_THREADS is defined (instead of just when _LIBCPP_FREESTANDING is defined), since there is no other way to implement <atomic> without thread support. Arguably, when building without thread support, one is effectively doing a freestanding compilation, so one could require the user to supply “-ffreestanding”. However, it seems that this is not usually done on the systems I work with. Furthermore, it is conceivable that one wants to build libc++ for a hosted platform that does not supports threads but still would want to have support for atomics.
3. In `memory.cpp`, change `#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER` to `#ifdef _LIBCPP_HAS_NO_THREADS`. Since this ifdef protects against the use of threading primitives, the latter seems more correct, while the former leads to compilation errors with the new logic for _LIBCPP_HAS_NO_ATOMIC_HEADER. It seems to indicate that the implementation of `<memory>` uses threading primitives instead of atomics. Therefore, in standalone builds, where concurrency comes in the form of interrupts rather than threads, one has to be careful with the use of `<memory>`. If at some point libc++ on baremetal becomes officially supported, that issue should probably be documented somewhere.

Of course, so far my patch fails to provide tests for the issue, which I’m not sure how to proceed with. I have never run any of the LLVM tests myself, as this seems to be extra challenging for cross-builds for baremetal.  I did manually test the built libc++ in a simple (“blinky”) project that uses hardware timer interrupts to trigger state changes, relying on <atomic> for synchronisation. It appears to work, contrary to the non-atomic version of it.


Repository:
  rCXX libc++

https://reviews.llvm.org/D65348

Files:
  libcxx/include/__config
  libcxx/include/atomic
  libcxx/src/memory.cpp


Index: libcxx/src/memory.cpp
===================================================================
--- libcxx/src/memory.cpp
+++ libcxx/src/memory.cpp
@@ -134,7 +134,7 @@
 
 #endif  // _LIBCPP_NO_RTTI
 
-#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
+#if !defined(_LIBCPP_HAS_NO_THREADS)
 
 _LIBCPP_SAFE_STATIC static const std::size_t __sp_mut_count = 16;
 _LIBCPP_SAFE_STATIC static __libcpp_mutex_t mut_back[__sp_mut_count] =
@@ -185,7 +185,7 @@
     return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
 }
 
-#endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
+#endif // !defined(_LIBCPP_HAS_NO_THREADS)
 
 void
 declare_reachable(void*)
Index: libcxx/include/atomic
===================================================================
--- libcxx/include/atomic
+++ libcxx/include/atomic
@@ -556,9 +556,6 @@
 #pragma GCC system_header
 #endif
 
-#ifdef _LIBCPP_HAS_NO_THREADS
-# error <atomic> is not supported on this single threaded system
-#endif
 #ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
 # error <atomic> is not implemented
 #endif
Index: libcxx/include/__config
===================================================================
--- libcxx/include/__config
+++ libcxx/include/__config
@@ -1148,14 +1148,13 @@
 
 #if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && \
      !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \
-     !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP)) \
-     || defined(_LIBCPP_HAS_NO_THREADS)
+     !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP))
 #  define _LIBCPP_HAS_NO_ATOMIC_HEADER
 #else
 #  ifndef _LIBCPP_ATOMIC_FLAG_TYPE
 #    define _LIBCPP_ATOMIC_FLAG_TYPE bool
 #  endif
-#  ifdef _LIBCPP_FREESTANDING
+#  if defined(_LIBCPP_FREESTANDING) || defined(_LIBCPP_HAS_NO_THREADS)
 #    define _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
 #  endif
 #endif


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65348.211997.patch
Type: text/x-patch
Size: 1752 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20190726/e0436b99/attachment-0001.bin>


More information about the libcxx-commits mailing list