[libcxx-commits] [PATCH] D56913: decoupling Freestanding atomic<T> from libatomic.a

Louis Dionne via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Feb 11 10:47:52 PST 2019


ldionne requested changes to this revision.
ldionne added a comment.
This revision now requires changes to proceed.

Here's a summary of what I understand the current state of the patch is (mostly for my own reference as a bird's eye view):

  #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
  
      template <typename _Tp>
      struct __cxx_atomic_type {
          // Implementation using a raw _Tp and GCC's __atomic_xxx operations
      };
  
      template<typename _Tp>
      using __cxx_atomic_base_impl = __cxx_atomic_type<_Tp>;
  
  #elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
  
      template <typename _Tp>
      struct __cxx_atomic_type {
          // Implementation using an _Atomic(_Tp) and the __c11_atomic_xxx operations
      };
  
      template<typename _Tp>
      using __cxx_atomic_base_impl = __cxx_atomic_type<_Tp>;
  
  #endif
  
  
  #if defined(_LIBCPP_FREESTANDING) && defined(__cpp_lib_atomic_is_always_lock_free)
  
      template<typename _Tp>
      struct __cxx_atomic_lock_impl {
          // Implementation using a raw _Tp and a lock implemented as a __cxx_atomic_base_impl
      };
  
      template <class _Tp>
      using __cxx_atomic_impl = _Tp is always lock free ? __cxx_atomic_base_impl<_Tp> : __cxx_atomic_lock_impl<_Tp>;
  
  #else
  
      template <class _Tp>
      using __cxx_atomic_impl = __cxx_atomic_base_impl<_Tp>;
  
  #endif
  
  template <class _Tp>
  struct __atomic_base {
      // Implements the interface of <atomic> and uses a __cxx_atomic_impl<_Tp> under the hood
  };

Would it make sense to decide whether we want to use GCC's non-lockfree atomics or not based on a configuration macro that's not `_LIBCPP_FREESTANDING`?



================
Comment at: libcxx/include/atomic:555
 #endif
-#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
+#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && \
+    !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \
----------------
Wouldn't it be simpler to say:

```
#if defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
#  error <atomic> is not implemented
#endif
```


================
Comment at: libcxx/include/atomic:592
+
+template <typename _Tp> _Tp const& __create();
+template <typename _Tp> _Tp& __use();
----------------
I think uses of this can be replaced by `declval<_Tp const&>()`?


================
Comment at: libcxx/include/atomic:602
+  static const bool value =
+      sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char);
+};
----------------
Would `std::is_assignable<_Td&, _Tp const&>` work too instead? Those traits are available even in C++03 mode.


================
Comment at: libcxx/include/atomic:641-642
+  char* from = reinterpret_cast<char*>(&__val);
+  while (to != end)
+    *to++ = *from++;
+}
----------------
Can you use `_VSTD::copy(to, end, from)` instead? Also, you should mangle the names to `__to`, `__end` and `__from`.

I admit that having to include `<algorithm>` here sucks, but at least please lift this definition into a function you can reuse below. In the future we should simply put `copy` and other basic algorithms in a header like `<__algorithm_base>` that can be used in places where we don't need all of `<algorithm>`.

EDIT: Nevermind this: I just saw this was a pre-existing condition in the code. Keeping the comment here to point out this is not great, but you don't have to fix it in this patch.


================
Comment at: libcxx/include/atomic:718
 template <typename _Tp>
-struct __gcc_atomic_t {
+struct __cxx_atomic_type {
 
----------------
I'm not seeing the value of this type not being called `__cxx_atomic_base_impl` directly. Is there any reason for this?


================
Comment at: libcxx/include/atomic:973
+template <typename _Tp>
+struct __cxx_atomic_type {
+
----------------
Likewise, this type could be called `__cxx_atomic_base_impl` directly?


================
Comment at: libcxx/include/atomic:1146
+
 #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP
 
----------------
This `#endif` doesn't look right anymore.


================
Comment at: libcxx/include/atomic:1199
+
+  _LIBCPP_INLINE_VISIBILITY _Tp reader() const volatile {
+    _Tp __old;
----------------
`__reader` & friends should be mangled.


================
Comment at: libcxx/include/atomic:1215
+  _LIBCPP_INLINE_VISIBILITY void writer(_Function && __f) volatile {
+    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire));
+    __f(__a_value);
----------------
Can you please put the semi-colon on its own line, like so:

```
while (1 == __cxx_atomic_exchange(...))
    /* spin */;
```

or something like that. Just to make it obvious we're not calling `__f` in the loop. This applies elsewhere too.



Repository:
  rCXX libc++

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56913/new/

https://reviews.llvm.org/D56913





More information about the libcxx-commits mailing list