I have isolated a problem in pthread_cond_timedwait when the condattr is used to set the clock type to CLOCK_MONOTONIC. In this case even though a target time point in the future is specified, the call returns ETIMEDOUT but a subsequent call to clock_gettime(CLOCK_MONOTONIC) shows the desired time point was not reached.
$ gcc timed_wait_short.c -o timed_wait_short $ ./timed_wait_short.exe begin: 521036s 122315900n target: 521036s 172315900n end: 521036s 173293100n ok: true begin: 521036s 174872400n target: 521036s 224872400n end: 521036s 224378900n ok: false Jim@pulsar /cygdrive/c/users/jim/desktop $ ./timed_wait_short.exe begin: 521052s 95953200n target: 521052s 145953200n end: 521052s 145284000n ok: false Jim@pulsar /cygdrive/c/users/jim/desktop $ ./timed_wait_short.exe begin: 521056s 396277200n target: 521056s 446277200n end: 521056s 446664700n ok: true begin: 521056s 454535100n target: 521056s 504535100n end: 521056s 504567000n ok: true begin: 521056s 510360800n target: 521056s 560360800n end: 521056s 560555600n ok: true begin: 521056s 566604400n target: 521056s 616604400n end: 521056s 616622800n ok: true begin: 521056s 619277800n target: 521056s 669277800n end: 521056s 669646400n ok: true begin: 521056s 671907500n target: 521056s 721907500n end: 521056s 721578000n ok: false I have attached the source code. Cygwin DLL version info: DLL version: 2.11.2 DLL epoch: 19 DLL old termios: 5 DLL malloc env: 28 Cygwin conv: 181 API major: 0 API minor: 329 Shared data: 5 DLL identifier: cygwin1 Mount registry: 3 Cygwin registry name: Cygwin Installations name: Installations Cygdrive default prefix: Build date: Shared id: cygwin1S5
/* * Copyright (C) 2018 James E. King III * * This test exposes a problem in cygwin's condition variable clock * handling when setclock(CLOCK_MONOTONIC) is used on the attribute. * * Although ETIMEDOUT is being returned by pthread_cond_timedwait, * a subsequent fetch of the clock shows that the time point was not * reached. */ #include <assert.h> #include <errno.h> #include <pthread.h> #include <stdio.h> #include <time.h> int main() { int ok; pthread_cond_t cv; pthread_condattr_t attr; pthread_mutex_t m; assert(!pthread_condattr_init(&attr)); pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); assert(!pthread_mutex_init(&m, NULL)); assert(!pthread_cond_init(&cv, &attr)); pthread_condattr_destroy(&attr); assert(!pthread_mutex_lock(&m)); do { struct timespec ts_begin; struct timespec ts_target; struct timespec ts_end; assert(!clock_gettime(CLOCK_MONOTONIC, &ts_begin)); ts_target = ts_begin; ts_target.tv_nsec += 50000000; // add 50ms if (ts_target.tv_nsec >= 1000000000) { ++ts_target.tv_sec; ts_target.tv_nsec -= 1000000000; } assert(ETIMEDOUT == pthread_cond_timedwait(&cv, &m, &ts_target)); assert(!clock_gettime(CLOCK_MONOTONIC, &ts_end)); ok = ts_end.tv_sec > ts_target.tv_sec || (ts_end.tv_sec == ts_target.tv_sec && ts_end.tv_nsec >= ts_target.tv_nsec); printf(" begin: %10us %10un\n", ts_begin.tv_sec, ts_begin.tv_nsec); printf("target: %10us %10un\n", ts_target.tv_sec, ts_target.tv_nsec); printf(" end: %10us %10un\n", ts_end.tv_sec, ts_end.tv_nsec); printf(" ok: %s\n", ok ? "true" : "false"); } while (ok); pthread_mutex_unlock(&m); pthread_mutex_destroy(&m); pthread_cond_destroy(&cv); return !ok; }
-- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple