From: Jonathan Wakely Date: Wed, 8 Aug 2018 15:40:41 +0000 (+0100) Subject: PR libstdc++/68519 use native duration to avoid rounding errors X-Git-Tag: releases/gcc-6.5.0~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=62ea33bbef023e14cace6c54487741b249429ed8;p=thirdparty%2Fgcc.git PR libstdc++/68519 use native duration to avoid rounding errors Backport from mainline 2017-12-14 Jonathan Wakely PR libstdc++/68519 * include/std/condition_variable (condition_variable::wait_for): Convert duration to native clock's duration before addition. * testsuite/30_threads/condition_variable/members/68519.cc: New test. From-SVN: r263420 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b278cc5ecc0e..9740f022408c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,13 @@ 2018-08-08 Jonathan Wakely + Backport from mainline + 2017-12-14 Jonathan Wakely + + PR libstdc++/68519 + * include/std/condition_variable (condition_variable::wait_for): + Convert duration to native clock's duration before addition. + * testsuite/30_threads/condition_variable/members/68519.cc: New test. + Backport from mainline 2018-06-25 Jonathan Wakely diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable index 62a7ee145196..8b3b6bc7aaaa 100644 --- a/libstdc++-v3/include/std/condition_variable +++ b/libstdc++-v3/include/std/condition_variable @@ -135,14 +135,26 @@ _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 __clock_t::duration; + auto __reltime = chrono::duration_cast<__dur>(__rtime); + if (__reltime < __rtime) + ++__reltime; + return wait_until(__lock, __clock_t::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 __clock_t::duration; + auto __reltime = chrono::duration_cast<__dur>(__rtime); + if (__reltime < __rtime) + ++__reltime; + return wait_until(__lock, __clock_t::now() + __reltime, std::move(__p)); + } native_handle_type native_handle() diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc new file mode 100644 index 000000000000..71c1d29e2312 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc @@ -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(); +}