Package: datefudge
Version: 1.24

The test programs below should sleep for 2 seconds. However, under datefudge '1 
second', they actually sleep for 3 seconds, and under datefudge '1 second ago', 
they only sleep for 1 second. This seems to be because datefudge adjusts the 
clock_gettime() call, but not the pthread_cond_timedwait() call or the futex() 
call that implements it.

I noticed this while using threading.Thread.join(timeout) in Python 3.6. 
(Python 3.8 has since changed that to use CLOCK_MONOTONIC: 
https://bugs.python.org/issue12822.)

First test program, using pthread_cond_timedwait() (compile with gcc -pthread):

#include <pthread.h>
#include <stdio.h>
#include <time.h>

int main() {
  pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  pthread_mutex_lock(&mutex);
  struct timespec timeout;
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += 2;
  printf("sleeping\n");
  pthread_cond_timedwait(&cond, &mutex, &timeout);
  printf("done\n");
  return 0;
}

Second test program, using futex() directly:

#include <linux/futex.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <time.h>
#include <unistd.h>

int main() {
  uint32_t u = 123;
  struct timespec timeout;
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += 2;
  printf("sleeping\n");
  syscall(SYS_futex, &u, FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, 123,
          &timeout, FUTEX_BITSET_MATCH_ANY);
  printf("done\n");
  return 0;
}

Reply via email to