From 9743598d212c5b97a976bf760e70a09ab66d56c0 Mon Sep 17 00:00:00 2001 From: xiezhiheng Date: Wed, 28 Apr 2021 11:11:14 +0800 Subject: [PATCH] PR libstdc++/41861 Add full steady_clock support to condition_variable --- ..._clock-support-to-condition_variable.patch | 363 ++++++++++++++++++ gcc.spec | 10 +- 2 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 Add-full-steady_clock-support-to-condition_variable.patch diff --git a/Add-full-steady_clock-support-to-condition_variable.patch b/Add-full-steady_clock-support-to-condition_variable.patch new file mode 100644 index 0000000..97d8883 --- /dev/null +++ b/Add-full-steady_clock-support-to-condition_variable.patch @@ -0,0 +1,363 @@ +This backport contains 4 patch from gcc main stream tree. +The commit id of these patchs list as following in the order of time. + +0001-PR-libstdc++-68519-use-native-duration-to-avoid-rounding.patch +83fd5e73b3c16296e0d7ba54f6c547e01c7eae7b + +0001-Use-steady_clock-to-implement-condition_variable-wait_for.patch +9e68aa3cc52956ea99bb726c3c29ce0581b9f7e7 + +0001-Use-steady_clock-to-implement-condition_variable-wait_for.patch +29b26763f5552129996bfc732cfa2087d7c9657c + +0001-PR-libstdc++-41861-Add-full-steady_clock-support-to.patch +ad4d1d21ad5c515ba90355d13b14cbb74262edd2 + +diff -Nurp a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 +--- a/libstdc++-v3/acinclude.m4 2021-04-25 03:41:20.232000000 +0800 ++++ b/libstdc++-v3/acinclude.m4 2021-04-25 03:42:23.352000000 +0800 +@@ -4092,6 +4092,37 @@ AC_DEFUN([GLIBCXX_CHECK_PTHREADS_NUM_PRO + ]) + + dnl ++dnl Check whether pthread_cond_clockwait is available in for std::condition_variable to use, ++dnl and define _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT. ++dnl ++AC_DEFUN([GLIBCXX_CHECK_PTHREAD_COND_CLOCKWAIT], [ ++ ++ AC_LANG_SAVE ++ AC_LANG_CPLUSPLUS ++ ac_save_CXXFLAGS="$CXXFLAGS" ++ CXXFLAGS="$CXXFLAGS -fno-exceptions" ++ ac_save_LIBS="$LIBS" ++ LIBS="$LIBS -lpthread" ++ ++ AC_MSG_CHECKING([for pthread_cond_clockwait]) ++ AC_CACHE_VAL(glibcxx_cv_PTHREAD_COND_CLOCKWAIT, [ ++ GCC_TRY_COMPILE_OR_LINK( ++ [#include ], ++ [pthread_mutex_t mutex; pthread_cond_t cond; struct timespec ts; int n = pthread_cond_clockwait(&cond, &mutex, 0, &ts);], ++ [glibcxx_cv_PTHREAD_COND_CLOCKWAIT=yes], ++ [glibcxx_cv_PTHREAD_COND_CLOCKWAIT=no]) ++ ]) ++ if test $glibcxx_cv_PTHREAD_COND_CLOCKWAIT = yes; then ++ AC_DEFINE(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT, 1, [Define if pthread_cond_clockwait is available in .]) ++ fi ++ AC_MSG_RESULT($glibcxx_cv_PTHREAD_COND_CLOCKWAIT) ++ ++ CXXFLAGS="$ac_save_CXXFLAGS" ++ LIBS="$ac_save_LIBS" ++ AC_LANG_RESTORE ++]) ++ ++dnl + dnl Check whether sysctl is available in , and define _GLIBCXX_USE_SYSCTL_HW_NCPU. + dnl + AC_DEFUN([GLIBCXX_CHECK_SYSCTL_HW_NCPU], [ +diff -Nurp a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in +--- a/libstdc++-v3/config.h.in 2021-04-25 03:41:20.220000000 +0800 ++++ b/libstdc++-v3/config.h.in 2021-04-25 03:42:23.352000000 +0800 +@@ -939,6 +939,9 @@ + /* Define if pthreads_num_processors_np is available in . */ + #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP + ++/* Define if pthread_cond_clockwait is available in . */ ++#undef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT ++ + /* Define if POSIX read/write locks are available in . */ + #undef _GLIBCXX_USE_PTHREAD_RWLOCK_T + +diff -Nurp a/libstdc++-v3/configure b/libstdc++-v3/configure +--- a/libstdc++-v3/configure 2021-04-25 03:41:20.220000000 +0800 ++++ b/libstdc++-v3/configure 2021-04-25 03:42:23.364000000 +0800 +@@ -21264,6 +21264,89 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + ++# For pthread_cond_clockwait ++ ++ ++ ++ ac_ext=cpp ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++ ac_save_CXXFLAGS="$CXXFLAGS" ++ CXXFLAGS="$CXXFLAGS -fno-exceptions" ++ ac_save_LIBS="$LIBS" ++ LIBS="$LIBS -lpthread" ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_cond_clockwait" >&5 ++$as_echo_n "checking for pthread_cond_clockwait... " >&6; } ++ if ${glibcxx_cv_PTHREAD_COND_CLOCKWAIT+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ++ if test x$gcc_no_link = xyes; then ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++int ++main () ++{ ++pthread_mutex_t mutex; pthread_cond_t cond; struct timespec ts; int n = pthread_cond_clockwait(&cond, &mutex, 0, &ts); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_compile "$LINENO"; then : ++ glibcxx_cv_PTHREAD_COND_CLOCKWAIT=yes ++else ++ glibcxx_cv_PTHREAD_COND_CLOCKWAIT=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++else ++ if test x$gcc_no_link = xyes; then ++ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 ++fi ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++int ++main () ++{ ++pthread_mutex_t mutex; pthread_cond_t cond; struct timespec ts; int n = pthread_cond_clockwait(&cond, &mutex, 0, &ts); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_link "$LINENO"; then : ++ glibcxx_cv_PTHREAD_COND_CLOCKWAIT=yes ++else ++ glibcxx_cv_PTHREAD_COND_CLOCKWAIT=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++ ++fi ++ ++ if test $glibcxx_cv_PTHREAD_COND_CLOCKWAIT = yes; then ++ ++$as_echo "#define _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT 1" >>confdefs.h ++ ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_PTHREAD_COND_CLOCKWAIT" >&5 ++$as_echo "$glibcxx_cv_PTHREAD_COND_CLOCKWAIT" >&6; } ++ ++ CXXFLAGS="$ac_save_CXXFLAGS" ++ LIBS="$ac_save_LIBS" ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++ + + ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default" + if test "x$ac_cv_header_locale_h" = x""yes; then : +diff -Nurp a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac +--- a/libstdc++-v3/configure.ac 2021-04-25 03:41:20.220000000 +0800 ++++ b/libstdc++-v3/configure.ac 2021-04-25 03:42:23.364000000 +0800 +@@ -220,6 +220,9 @@ GLIBCXX_ENABLE_LIBSTDCXX_TIME + # Check for tmpnam which is obsolescent in POSIX.1-2008 + GLIBCXX_CHECK_TMPNAM + ++# For pthread_cond_clockwait ++GLIBCXX_CHECK_PTHREAD_COND_CLOCKWAIT ++ + AC_LC_MESSAGES + + # For hardware_concurrency +diff -Nurp a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable +--- a/libstdc++-v3/include/std/condition_variable 2021-04-25 03:41:19.916000000 +0800 ++++ b/libstdc++-v3/include/std/condition_variable 2021-04-25 03:42:23.364000000 +0800 +@@ -64,7 +64,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + /// condition_variable + class condition_variable + { +- typedef chrono::system_clock __clock_t; ++ using steady_clock = chrono::steady_clock; ++ using system_clock = chrono::system_clock; ++#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT ++ using __clock_t = steady_clock; ++#else ++ using __clock_t = system_clock; ++#endif + typedef __gthread_cond_t __native_type; + + #ifdef __GTHREAD_COND_INIT +@@ -99,10 +105,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + wait(__lock); + } + ++#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT ++ template ++ cv_status ++ wait_until(unique_lock& __lock, ++ const chrono::time_point& __atime) ++ { return __wait_until_impl(__lock, __atime); } ++#endif ++ + template + cv_status + wait_until(unique_lock& __lock, +- const chrono::time_point<__clock_t, _Duration>& __atime) ++ const chrono::time_point& __atime) + { return __wait_until_impl(__lock, __atime); } + + template +@@ -110,7 +124,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + wait_until(unique_lock& __lock, + const chrono::time_point<_Clock, _Duration>& __atime) + { +- // DR 887 - Sync unknown clock to known clock. + const typename _Clock::time_point __c_entry = _Clock::now(); + const __clock_t::time_point __s_entry = __clock_t::now(); + const auto __delta = __atime - __c_entry; +@@ -135,24 +148,61 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + cv_status + wait_for(unique_lock& __lock, + const chrono::duration<_Rep, _Period>& __rtime) +- { return wait_until(__lock, __clock_t::now() + __rtime); } ++ { ++ using __dur = typename steady_clock::duration; ++ auto __reltime = chrono::duration_cast<__dur>(__rtime); ++ if (__reltime < __rtime) ++ ++__reltime; ++ return wait_until(__lock, steady_clock::now() + __reltime); ++ } + + template + bool + wait_for(unique_lock& __lock, + const chrono::duration<_Rep, _Period>& __rtime, + _Predicate __p) +- { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); } ++ { ++ using __dur = typename steady_clock::duration; ++ auto __reltime = chrono::duration_cast<__dur>(__rtime); ++ if (__reltime < __rtime) ++ ++__reltime; ++ return wait_until(__lock, steady_clock::now() + __reltime, ++ std::move(__p)); ++ } + + native_handle_type + native_handle() + { return &_M_cond; } + + private: ++#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT ++ template ++ cv_status ++ __wait_until_impl(unique_lock& __lock, ++ const chrono::time_point& __atime) ++ { ++ auto __s = chrono::time_point_cast(__atime); ++ auto __ns = chrono::duration_cast(__atime - __s); ++ ++ __gthread_time_t __ts = ++ { ++ static_cast(__s.time_since_epoch().count()), ++ static_cast(__ns.count()) ++ }; ++ ++ pthread_cond_clockwait(&_M_cond, __lock.mutex()->native_handle(), ++ CLOCK_MONOTONIC, ++ &__ts); ++ ++ return (steady_clock::now() < __atime ++ ? cv_status::no_timeout : cv_status::timeout); ++ } ++#endif ++ + template + cv_status + __wait_until_impl(unique_lock& __lock, +- const chrono::time_point<__clock_t, _Dur>& __atime) ++ const chrono::time_point& __atime) + { + auto __s = chrono::time_point_cast(__atime); + auto __ns = chrono::duration_cast(__atime - __s); +@@ -166,7 +216,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(), + &__ts); + +- return (__clock_t::now() < __atime ++ return (system_clock::now() < __atime + ? cv_status::no_timeout : cv_status::timeout); + } + }; +@@ -186,7 +236,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + // Like above, but mutex is not required to have try_lock. + class condition_variable_any + { +- typedef chrono::system_clock __clock_t; ++#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT ++ using __clock_t = chrono::steady_clock; ++#else ++ using __clock_t = chrono::system_clock; ++#endif + condition_variable _M_cond; + shared_ptr _M_mutex; + +diff -Nurp a/libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc +--- a/libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc 1970-01-01 08:00:00.000000000 +0800 ++++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc 2021-04-25 03:41:43.008000000 +0800 +@@ -0,0 +1,51 @@ ++// Copyright (C) 2017 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. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING3. If not see ++// . ++ ++// { dg-do run } ++// { dg-options "-pthread" } ++// { dg-require-effective-target c++11 } ++// { dg-require-effective-target pthread } ++// { dg-require-cstdint "" } ++// { dg-require-gthreads "" } ++ ++#include ++#include ++ ++// PR libstdc++/68519 ++ ++bool val = false; ++std::mutex mx; ++std::condition_variable cv; ++ ++void ++test01() ++{ ++ for (int i = 0; i < 3; ++i) ++ { ++ std::unique_lock l(mx); ++ auto start = std::chrono::system_clock::now(); ++ cv.wait_for(l, std::chrono::duration(1), [] { return val; }); ++ auto t = std::chrono::system_clock::now(); ++ VERIFY( (t - start) >= std::chrono::seconds(1) ); ++ } ++} ++ ++int ++main() ++{ ++ test01(); ++} diff --git a/gcc.spec b/gcc.spec index 85f181e..2361604 100644 --- a/gcc.spec +++ b/gcc.spec @@ -1,4 +1,4 @@ -%global DATE 20210203 +%global DATE 20210428 %define debug_package %{nil} %global gcc_version 7.3.0 @@ -37,7 +37,7 @@ Summary: Various compilers (C, C++, Objective-C, Java, ...) Name: gcc Version: 7.3.0 -Release: %{DATE}.37 +Release: %{DATE}.38 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD Group: Development/Languages #Source0: hcc-aarch64-linux-release.tar.bz2 @@ -86,6 +86,7 @@ Patch31: fstack-clash-protection.patch Patch34: mark-pattern-as-clobbering-CC-REGNUM.patch Patch35: turn-on-funwind-tables-by-default.patch Patch36: fix-trivially_constructible-PR81589.patch +Patch37: Add-full-steady_clock-support-to-condition_variable.patch #AutoReqProv: off AutoReq: true @@ -546,6 +547,7 @@ package or when debugging this package. %patch34 -p1 %patch35 -p1 %patch36 -p1 +%patch37 -p1 %if 0%{?_enable_debug_packages} cat > split-debuginfo.sh <<\EOF @@ -3284,6 +3286,10 @@ fi %changelog +* Wed Apr 28 2021 eastb233 - 7.3.0-20210428.38 +- Add-full-steady_clock-support-to-condition_variable.patch: New file +- gcc.spec: Add new patch + * Wed Mar 17 2021 tianwei - 7.3.0-20210203.37 - Type:bugfix - ID:NA -- Gitee