-----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

Reply via email to