[PATCH] Add C++2a synchronization support
Jonathan Wakely
jwakely@redhat.com
Mon Aug 3 20:19:23 GMT 2020
On 03/08/20 15:09 +0100, Jonathan Wakely wrote:
>On 05/06/20 17:29 -0700, Thomas Rodgers wrote:
>>diff --git a/libstdc++-v3/include/bits/semaphore_base.h b/libstdc++-v3/include/bits/semaphore_base.h
>>new file mode 100644
>>index 00000000000..f0c4235d91c
>>--- /dev/null
>>+++ b/libstdc++-v3/include/bits/semaphore_base.h
>>@@ -0,0 +1,272 @@
>>+// -*- C++ -*- header.
>>+
>>+// Copyright (C) 2020 Free Software Foundation, Inc.
>>+//
>>+// This file is part of the GNU ISO C++ Library. This library is free
>>+// software; you can redistribute it and/or modify it under the
>>+// terms of the GNU General Public License as published by the
>>+// Free Software Foundation; either version 3, or (at your option)
>>+// any later version.
>>+
>>+// This library is distributed in the hope that it will be useful,
>>+// but WITHOUT ANY WARRANTY; without even the implied warranty of
>>+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>+// GNU General Public License for more details.
>>+
>>+// Under Section 7 of GPL version 3, you are granted additional
>>+// permissions described in the GCC Runtime Library Exception, version
>>+// 3.1, as published by the Free Software Foundation.
>>+
>>+// You should have received a copy of the GNU General Public License and
>>+// a copy of the GCC Runtime Library Exception along with this program;
>>+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
>>+// <http://www.gnu.org/licenses/>.
>>+
>>+/** @file bits/semaphore_base.h
>>+ * This is an internal header file, included by other library headers.
>>+ * Do not attempt to use it directly. @headername{semaphore}
>>+ */
>>+
>>+#ifndef _GLIBCXX_SEMAPHORE_BASE_H
>>+#define _GLIBCXX_SEMAPHORE_BASE_H 1
>>+
>>+#pragma GCC system_header
>>+
>>+#include <bits/c++config.h>
>>+#include <bits/atomic_base.h>
>>+#include <bits/atomic_timed_wait.h>
>>+
>>+#if defined _POSIX_SEMAPHORES && __has_include(<semaphore.h>)
>>+#define _GLIBCXX_HAVE_POSIX_SEMAPHORE 1
>>+#include <semaphore.h>
>>+#endif
>>+
>>+#include <chrono>
>>+#include <type_traits>
>>+
>>+namespace std _GLIBCXX_VISIBILITY(default)
>>+{
>>+_GLIBCXX_BEGIN_NAMESPACE_VERSION
>>+
>>+#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
>>+ template<ptrdiff_t __least_max_value>
>>+ struct __platform_semaphore
Why is this a template?
It means we'll instantiate identical code for counting_semaphore<3>
and counting_semaphore<4>, but they're distinct types that will bloat
the binary.
Can't we just have a single __platform_semaphore type for all max
values, and just make sure we don't instantiate it for values larger
than SEM_VALUE_MAX?
>>+ {
>
>I think we want to delete the copy constructor and copy assignment
>operator for this type and __atomic_semaphore.
>
>>+ using __clock_t = chrono::system_clock;
>>+
>>+ explicit __platform_semaphore(ptrdiff_t __count) noexcept
>>+ {
>>+ static_assert( __least_max_value <= SEM_VALUE_MAX, "");
I think it would be useful for __platform_semaphore to define a static
constexpr member like:
static constexpr ptrdiff_t _S_max = SEM_VALUE_MAX;
And then __atomic_semaphore could define:
static constexpr _Tp _S_max = __gnu_cxx::__int_traits<_Tp>::__max;
And then the alias __semaphore_base could be defined as:
#if _GLIBCXX_HAVE_LINUX_FUTEX && ! _GLIBCXX_REQUIRE_POSIX_SEMAPHORE
// Use futex if available and user didn't force use of POSIX:
using __fast_semaphore_base = __atomic_semaphore<__platform_wait_t>;
#elif _GLIBCXX_HAVE_POSIX_SEMAPHORE
// Otherwise, use POSIX if available:
using __fast_semaphore_base = __platform_semaphore<SEM_VALUE_MAX>;
#else
// Otherwise, use atomics:
using __fast_semaphore_base = __atomic_semaphore<ptrdiff_t>;
#endif
template<ptrdiff_t __least_max_value>
using __semaphore_base = conditional_t<
__least_max_value <= __fast_semaphore_base::_S_max,
__fast_semaphore_base, __atomic_semaphore<ptrdiff_t>;
Would that make sense?
Do the comments above reflect the intent?
>>+#ifdef _GLIBCXX_REQUIRE_POSIX_SEMAPHORE
>
>What is this case for? This macro seems to only exist for use by a
>single testcase.
>
>Is it supposed to be something users can set? If so, it needs to be
>documented as ABI-breaking and as implying that counting_semaphore
>cannot be use with counts higher than SEM_VALUE_MAX.
>
>>+ template<ptrdiff_t __least_max_value>
>>+ using __semaphore_base = __platform_semaphore<__least_max_value>;
>>+#else
>>+# ifdef _GLIBCXX_HAVE_LINUX_FUTEX
>>+ template<ptrdiff_t __least_max_value>
>>+ using __semaphore_base = conditional_t<(
>>+ __least_max_value >= 0
>
>This condition is redundant, we already know that counting_semaphore
>has checked the value is non-negative.
>
>>+ && __least_max_value <= __detail::__platform_wait_max_value),
>>+ __atomic_semaphore<__detail::__platform_wait_t>,
>>+ __atomic_semaphore<ptrdiff_t>>;
>>+
>>+// __platform_semaphore
>>+# elif defined _GLIBCXX_HAVE_POSIX_SEMAPHORE
>>+ template<ptrdiff_t __least_max_value>
>>+ using __semaphore_base = conditional_t<(
>>+ __least_max_value >= 0
>
>Redundant condition again.
>
>>+ && __least_max_value <= SEM_VALUE_MAX),
>>+ __platform_semaphore<__least_max_value>,
>>+ __atomic_semaphore<ptrdiff_t>>;
>>+# else
>>+ template<ptrdiff_t __least_max_value>
>>+ using __semaphore_base = __atomic_semaphore<ptrdiff_t>;
>>+# endif
>>+#endif
>>+
>>+_GLIBCXX_END_NAMESPACE_VERSION
>>+} // namespace std
>>+
>>+#endif
More information about the Libstdc++
mailing list