PR libstdc++/68519 use native duration to avoid rounding errors

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: r255665
This commit is contained in:
Jonathan Wakely 2017-12-14 20:41:52 +00:00 committed by Jonathan Wakely
parent d5f6f04c91
commit 83fd5e73b3
3 changed files with 70 additions and 2 deletions

View File

@ -1,5 +1,10 @@
2017-12-14 Jonathan Wakely <jwakely@redhat.com>
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.
PR libstdc++/83427
* include/bits/refwrap.h (_Maybe_unary_or_binary_function): Move here
from <bits/std_function.h>.

View File

@ -135,14 +135,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
cv_status
wait_for(unique_lock<mutex>& __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<typename _Rep, typename _Period, typename _Predicate>
bool
wait_for(unique_lock<mutex>& __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()

View File

@ -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
// <http://www.gnu.org/licenses/>.
// { dg-do run }
// { dg-options "-pthread" }
// { dg-require-effective-target c++11 }
// { dg-require-effective-target pthread }
// { dg-require-cstdint "" }
// { dg-require-gthreads "" }
#include <condition_variable>
#include <testsuite_hooks.h>
// 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<std::mutex> l(mx);
auto start = std::chrono::system_clock::now();
cv.wait_for(l, std::chrono::duration<float>(1), [] { return val; });
auto t = std::chrono::system_clock::now();
VERIFY( (t - start) >= std::chrono::seconds(1) );
}
}
int
main()
{
test01();
}