Jonathan Wakely writes:

> On 09/05/20 17:01 -0700, Thomas Rodgers via Libstdc++ wrote:

<snip>

>>+#include <iostream>
>
> <iostream> shouldn't be here (it adds runtime cost, as well as
> compile-time).
>
Oversight, not removed after debugging it.

<snip>

>
> Can't this just be __old instead of *std::__addressof(__old) ?
>
Copypasta from elsewhere in the same class, I believe. I'll change it.

<snip>

>
> Isn't alignas(64) already implied by the first data member?
>

Yes

>>+    {
>>+      int32_t alignas(64) _M_ver = 0;
>>+      int32_t alignas(64) _M_wait = 0;
>>+
>>+      // TODO make this used only where we don't have futexes
>
> Don't we always need these even with futexes, for the types that don't
> use a futex?
>

If we have futexes, we can use the address of _M_ver to wake
_M_do_wait() instead of using a condvar for types that don't use a
futex directly.

>>+      using __lock_t = std::unique_lock<std::mutex>;
>+      mutable __lock_t::mutex_type _M_mtx;
>>+
>>+#ifdef __GTHREAD_COND_INIT
>>+      mutable __gthread_cond_t _M_cv = __GTHREAD_COND_INIT;
>>+      __waiters() noexcept = default;
>
> If we moved std::condition_variable into its own header (or
> <bits/std_mutex.h>, could we reuse that here instead of using
> __gthread_cond_t directly?
>
Yes, I started down that route initially, I could revisit it in a future
patch as part of also making it's use only necessary when the platform
doesn't support futex.

>>+    __atomic_notify(const _Tp* __addr, bool __all) noexcept
>>+    {
>>+      using namespace __detail;
>>+      auto& __w = __waiters::_S_for((void*)__addr);
>>+      if (!__w._M_waiting())
>
> When __platform_wait_uses_type<_Tp> is true, will __w._M_waiting()
> ever be true? Won't this always return before notifying?
>
> Is there meant to be a __waiter constructed here?
>

__waiter (an RAII type) is constructed in the __atomic_wait(), that
increments the _M_wait count on the way into the wait, and decrements it
on the way out, __atomic_notify checks to see if that count is non-zero
before invoking the platform/semaphore notify because it is cheaper
to do the atomic load than it is to make the syscall() when there are no
waiters.

>>+     return;
>>+
>>+      if constexpr (__platform_wait_uses_type<_Tp>::__value)
>>+     {
>>+       __platform_notify((__platform_wait_t*)(void*) __addr, __all);
>>+     }

<snip>

>>+    struct __platform_semaphore
>>+    {
>>+      using __clock_t = chrono::system_clock;
>>+
>>+      __platform_semaphore(ptrdiff_t __count) noexcept
>
> Should this constructor be explicit?
>

Yes.

>>+      template<typename _Duration>
>>+     _GLIBCXX_ALWAYS_INLINE bool
>
> Do we really need this to be always_inline?
>
Probably not, copypasta from elsewhere in the same file.

>>+     __try_acquire_until_impl(const chrono::time_point<__clock_t>& __atime) 
>>noexcept
>>+     {
>>+       auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
>>+       auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);

<snip>

>>+    template<typename _Tp>
>>+      struct __atomic_semaphore
>>+      {
>>+     static constexpr size_t _S_alignment = __alignof__(_Tp);
>>+
>>+     __atomic_semaphore(_Tp __count)
>
> Should this be explicit?
>
Yes.

>>+    private:
>>+      alignas(_S_alignment) _Tp _M_a;
>
> Could this just use alignas(__alignof__(_Tp)) _Tp here? There's no
> need for the _S_alignment constant if it's only used in one place.
>
Yes.

>>+    };
>>+
>>+#ifdef _GLIBCXX_REQUIRE_POSIX_SEMAPHORE
>>+  template<ptrdiff_t __least_max_t>
>
> Rename __least_max_t here too.
>
>>+    using __semaphore_base = __platform_semaphore<__least_max_t>;
>>+#else
>>+#  ifdef _GLIBCXX_HAVE_LINUX_FUTEX
>>+  template<ptrdiff_t __least_max_t>
>>+    using __semaphore_base = std::conditional<(__least_max_t > 0
>
> This should use conditional_t<> not conditional<>::type.
>
> The least-max_value can't be negative. If it's zero, can't we use a
> futex or semaphore? So the '__least_max_t > 0' condition is wrong?
>

Yes.

>>+                                           && __least_max_t < 
>>std::numeric_limits<__detail::__platform_wait_t>::max()),
>
> Should that be <= rather than < ?
>

Likely.

>>+                                           
>>__atomic_semaphore<__detail::__platform_wait_t>,
>>+                                           
>>__atomic_semaphore<ptrdiff_t>>::type;
>>+                                         // __platform_semaphore
>>+#  else

<snip...>

Reply via email to