This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/53841] New: [C++11] condition_variable::wait_until() fails with high resolution clocks
- From: "redi at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 03 Jul 2012 15:58:47 +0000
- Subject: [Bug libstdc++/53841] New: [C++11] condition_variable::wait_until() fails with high resolution clocks
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53841
Bug #: 53841
Summary: [C++11] condition_variable::wait_until() fails with
high resolution clocks
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Keywords: rejects-valid
Severity: normal
Priority: P3
Component: libstdc++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: redi@gcc.gnu.org
GCC's condition_variable::wait_until knows how to convert from unknown clocks
to system_clock, although it has a problem:
// 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 chrono::nanoseconds __delta = __atime - __c_entry;
That last line fails to compile if _Clock is higher resolution than
system_clock (i.e. has a smaller period or uses a floating point
representation).
Here's a clock that corresponds to system_clock but uses
duration<double,ratio<1>> as its duration type:
#include <chrono>
#include <mutex>
#include <condition_variable>
namespace ch = std::chrono;
struct FPClock : ch::system_clock
{
typedef double rep;
typedef std::ratio<1> period;
typedef ch::duration<rep, period> duration;
typedef ch::time_point<FPClock> time_point;
static time_point now()
{ return time_point(duration(system_clock::now().time_since_epoch())); }
};
void f()
{
std::mutex mx;
std::unique_lock<std::mutex> l(mx);
std::condition_variable cv;
cv.wait_until(l, FPClock::now());
}
This fails to compile.
It could be fixed with duration_cast:
const chrono::nanoseconds __delta
= chrono::duration_cast<chrono::nanoseconds>(__atime - __c_entry);
but that loses precision and truncates the value, e.g. FPClock::duration(9e-10)
is converted to nanoseconds(0), but nanoseconds(1) would be better.
I think it needs to use a version of duration_cast that rounds up to the next
value representable as chrono::nanoseconds.