-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Here's a testcase, compile with gcc -g -O2 pthreads_relwait.c -o
pthreads_relwait.exe -lpthread
The testcase should succeed (return 0), and print into the console that it
waited for one second (or more). But when compiled against winpthreads it
returns early, usually a few milliseconds before the deadline (as measured by
QPC).
Tested on a fairly recent (a few months old) i686 mingw-w64 from MSYS2.
Just in case ML eats the attachment, here's the source code:
==================pthreads_relwait.c=====================
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <pthread.h>
#include <Windows.h>
#define USEC_PER_SEC 1000000
int func()
{
LARGE_INTEGER freq;
double usec_per_tick;
LARGE_INTEGER ticks;
if (!QueryPerformanceFrequency (&freq) || freq.QuadPart == 0)
return 1;
usec_per_tick = (double) USEC_PER_SEC / freq.QuadPart;
int64_t start;
LARGE_INTEGER start_ticks;
int64_t until;
pthread_mutex_t mutex;
if (pthread_mutex_init (&mutex, NULL) != 0)
return 2;
pthread_condattr_t attr;
pthread_cond_t cond;
pthread_condattr_init (&attr);
if (pthread_cond_init (&cond, &attr) != 0)
return 3;
pthread_condattr_destroy (&attr);
if (!QueryPerformanceCounter (&ticks))
return 4;
start = (int64_t) (ticks.QuadPart * usec_per_tick);
start_ticks = ticks;
until = start + 1000000 /* now + 1 second */;
pthread_mutex_lock (&mutex);
struct timespec ts;
int status = 0;
do
{
int64_t now;
int64_t relative;
if (!QueryPerformanceCounter (&ticks))
return 5;
now = (int64_t) (ticks.QuadPart * usec_per_tick);
if (until <= now)
break;
relative = until - now;
ts.tv_sec = relative / 1000000;
ts.tv_nsec = (relative % 1000000) * 1000;
status = pthread_cond_timedwait_relative_np (&cond,
&mutex,
&ts);
if (status != ETIMEDOUT && status != 0)
{
printf ("status %d\n", status);
return 6;
}
} while (status == 0);
int64_t after;
LARGE_INTEGER after_ticks;
if (!QueryPerformanceCounter (&ticks))
return 7;
after = (int64_t) (ticks.QuadPart * usec_per_tick);
after_ticks = ticks;
pthread_mutex_unlock (&mutex);
LARGE_INTEGER diff_ticks;
diff_ticks.QuadPart = after_ticks.QuadPart - start_ticks.QuadPart;
printf ("started at\n%lld\n"
", ended at\n%lld\n"
", aimed at\n%lld\n"
", difference is\n%lld\n",
start, after, until, after - until);
printf ("started at\n%lld ticks\n"
", ended at\n%lld ticks\n"
", difference is\n%lld ticks\n"
", with\n%lld ticks per second that is %f seconds)\n",
start_ticks, after_ticks, diff_ticks.QuadPart,
freq.QuadPart,
(double) diff_ticks.QuadPart / (double) freq.QuadPart);
if (after < until)
return 8;
pthread_cond_destroy (&cond);
pthread_mutex_destroy (&mutex);
}
int
main (int argc, char **argv)
{
int status = func ();
if (status != 0)
printf ("Non-zero exit code %d\n", status);
return 0;
}
========================================================
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEE4MWzR43wYaAzEA49ja3pJ2dZunQFAlsNw+kACgkQja3pJ2dZ
unQRqA//R9X4YmQBX1v4kZ4vzlGRQUWas4G+RJ/YRWLViFKWP35rcR0/2f6fEIV2
1hfzzL+P/SNXjKnLtaDmHmv1WfqJ1096WctLfivYjOFsmt5xMOrzNbzUUUEUykFr
gGe5pqE0VS/NYc1IY+un6walozuYSjkTid/9F/JbouD8lEg/niyQvbn7u9aoj14Q
ido4lMnnSP09o8/ZLVApEjSw+5jmqQlHPyrn+3yC59uLtDo9LErvqn1JAlA3eYWb
/gafYiDjQcE0dfxOad5t7K4Yc5iNyrcoE8zm2f+2/OxMnYF3CDd62ytJ7z6GHf/B
FLubl5vVQFYhOQoZtDm/HZtaPm+c47mjHpGinusk340alROvpUZItaIZLcuY0jF/
hosgezsaOaOhpMwg9/CfYXgjLtxtwbLEPBPxFOyWyGurSeOdg67BgRVWl8YY/kds
cqUDfQ0ViJ8d2yHAY05QGK8BX6fQq3pdDwS1SbPzoJwa9aF/oWsVQfVKAh2LPo0h
LUrEf5be71QS582QbWYegMRe428DvsBK+b2wBD/KbpHt9JipiEJqzbLUGk7iovsI
nk5AODNgq1eHh/A5yDIU5QKhOdTyBOoUU0XhqRgN8BDdYUnFWZzXgohKGv2+LVmf
eVUUfSoDQRuhL32tZcuA3XKe2Yd6LjywFqlYKBjUZznnNosyQ+4=
=b5fs
-----END PGP SIGNATURE-----
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <pthread.h>
#include <Windows.h>
#define USEC_PER_SEC 1000000
int func()
{
LARGE_INTEGER freq;
double usec_per_tick;
LARGE_INTEGER ticks;
if (!QueryPerformanceFrequency (&freq) || freq.QuadPart == 0)
return 1;
usec_per_tick = (double) USEC_PER_SEC / freq.QuadPart;
int64_t start;
LARGE_INTEGER start_ticks;
int64_t until;
pthread_mutex_t mutex;
if (pthread_mutex_init (&mutex, NULL) != 0)
return 2;
pthread_condattr_t attr;
pthread_cond_t cond;
pthread_condattr_init (&attr);
if (pthread_cond_init (&cond, &attr) != 0)
return 3;
pthread_condattr_destroy (&attr);
if (!QueryPerformanceCounter (&ticks))
return 4;
start = (int64_t) (ticks.QuadPart * usec_per_tick);
start_ticks = ticks;
until = start + 1000000 /* now + 1 second */;
pthread_mutex_lock (&mutex);
struct timespec ts;
int status = 0;
do
{
int64_t now;
int64_t relative;
if (!QueryPerformanceCounter (&ticks))
return 5;
now = (int64_t) (ticks.QuadPart * usec_per_tick);
if (until <= now)
break;
relative = until - now;
ts.tv_sec = relative / 1000000;
ts.tv_nsec = (relative % 1000000) * 1000;
status = pthread_cond_timedwait_relative_np (&cond,
&mutex,
&ts);
if (status != ETIMEDOUT && status != 0)
{
printf ("status %d\n", status);
return 6;
}
} while (status == 0);
int64_t after;
LARGE_INTEGER after_ticks;
if (!QueryPerformanceCounter (&ticks))
return 7;
after = (int64_t) (ticks.QuadPart * usec_per_tick);
after_ticks = ticks;
pthread_mutex_unlock (&mutex);
LARGE_INTEGER diff_ticks;
diff_ticks.QuadPart = after_ticks.QuadPart - start_ticks.QuadPart;
printf ("started at\n%lld\n"
", ended at\n%lld\n"
", aimed at\n%lld\n"
", difference is\n%lld\n",
start, after, until, after - until);
printf ("started at\n%lld ticks\n"
", ended at\n%lld ticks\n"
", difference is\n%lld ticks\n"
", with\n%lld ticks per second that is %f seconds)\n",
start_ticks, after_ticks, diff_ticks.QuadPart,
freq.QuadPart,
(double) diff_ticks.QuadPart / (double) freq.QuadPart);
if (after < until)
return 8;
pthread_cond_destroy (&cond);
pthread_mutex_destroy (&mutex);
}
int
main (int argc, char **argv)
{
int status = func ();
if (status != 0)
printf ("Non-zero exit code %d\n", status);
return 0;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public