pthread_cond_timedwait with setclock(CLOCK_MONOTONIC) times out early
James E. King III
jking@apache.org
Sun Nov 25 14:01:00 GMT 2018
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
-------------- next part --------------
/*
* 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;
}
-------------- next part --------------
--
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
More information about the Cygwin
mailing list