Closed jeking3 closed 5 years ago
Also happens in debug builds.
Interesting, so on cygwin (32-bit) time_t is currently 32 bits, with no option to change it. This could be an overflow issue that requires a cast. Looking into it.
Nope, doesn't seem to be that.
Thanks for the report and to be working on a fix.
This behavior is really bizarre, I added some code to loop back and ask for t0 again if it is zero:
do {
t0 = Clock::now();
if (t0 == time_point(duration(ns(0))))
std::cout << "RETRYING: t0 was 0" << std::endl;
} while (t0 == time_point(duration(ns(0))));
It happens a lot, but never takes more than one extra execution to "fix" it (loop.sh runs the same test mentioned in the description 50 times, built debug mode):
Jim@pulsar /cygdrive/c/boost/libs/thread/test
$ ./loop.sh
No errors detected.
RETRYING: t0 was 0
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
RETRYING: t0 was 0
No errors detected.
RETRYING: t0 was 0
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
No errors detected.
No errors detected.
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
RETRYING: t0 was 0
No errors detected.
No errors detected.
No errors detected.
loop.sh:
#!/bin/bash
PATH="/cygdrive/c/boost/bin.v2/libs/atomic/build/gcc-7.3.0/dbg/cxstd-11-iso/thrd-mlt/vsblt-hdn:/cygdrive/c/boost/bin.v2/libs/chrono/build/gcc-7.3.0/dbg/cxstd-11-iso/thrd-mlt/vsblt-hdn:/cygdrive/c/boost/bin.v2/libs/system/build/gcc-7.3.0/dbg/cxstd-11-iso/thrd-mlt/vsblt-hdn:/cygdrive/c/boost/bin.v2/libs/thread/build/gcc-7.3.0/dbg/cxstd-11-iso/thrdp-pthrd/thrd-mlt/vsblt-hdn:/usr/bin:/usr/lib:/usr/lib32:/usr/lib64:$PATH"
for loop in {1..50}; do
../../../bin.v2/libs/thread/test/shared_lock__cons__try_to_lock_p.test/gcc-7.3.0/rls/cxstd-11-iso/thrdp-pthrd/thrd-mlt/vsblt-hdn/shared_lock__cons__try_to_lock_p
done
I found the root cause. Down inside cygwin there is one-time initialization code for the hires_ns::prime
call inside winsup/cygwin/times.cc
. The end result is that there is a race when two threads first call boost::chrono::high_resolution_clock::now() on cygwin. I have written a simple example outside of boost and I am submitting it to their mailing list. However, what this means is any call to ::clock_gettime
needs to be serialized on cygwin. I also saw a FIXME on gettimeofday
indicating thread safety needs to be added.
It looks like only calls to CLOCK_MONOTONIC need to be serialized for proper behavior.
I'm seeing this while building Boost.Thread in cygwin (32-bit). I added code to dump the values of t0 through t3 in the file
sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp
. When it fails, which seems to be about 75% of the time, t0 is zero (ran this from thread/test):If I call boost::chrono::high_resolution_clock::now() from the main thread before it gets called from the second thread, everything is fine.