4

I am trying to use pthread_cond_timedwait to wait with a timeout similar to Java's wait(long timeout, int nanos). I understand that Java's wait uses a relative timeout, whereas pthread_cond_timedwait uses an absolute time threshold. Despite taking this into account, pthread_cond_timedwait appears to return immediately with the error code ETIMEDOUT.

The sample program below prints a value <0. I would expect it to print a value >=0.

Am I using pthread_cond_timedwait incorrectly? How would I rewrite the below program to add a delay of e.g. 5 seconds?

#define _POSIX_C_SOURCE 199309L

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

int main(void) {
    pthread_mutex_t mutex;
    pthread_cond_t cond;

    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_mutex_lock(&mutex);

    struct timespec t1;
    struct timespec t2;

    clock_gettime(CLOCK_MONOTONIC, &t1);

    t1.tv_sec += 5;

    while(pthread_cond_timedwait(&cond, &mutex, &t1) != ETIMEDOUT);

    clock_gettime(CLOCK_MONOTONIC, &t2);

    printf("%d", t2.tv_sec - t1.tv_sec);

    pthread_mutex_unlock(&mutex);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    return 0;
}
fgsfdsfgts
  • 87
  • 2
  • 8
  • Interesting choice of POSIX version — were pthreads part of that? Have you done any error checking of the system calls? Have you considered printing anything in the body of the while loop? Have you considered printing the subsecond parts of the times? Which platform are you working on? – Jonathan Leffler Sep 02 '17 at 21:44
  • @JonathanLeffler The POSIX version is to get CLOCK_MONOTONIC to work on ideone.com. I got the solution from [link]https://stackoverflow.com/questions/40515557/compilation-error-on-clock-gettime-and-clock-monotonic[/link]. I'm working on Android (NDK) but the same thing happens on ideone.com (they use Linux I think). I haven't encountered any problems except with pthread_cond_timedwait. It just returns immediately with ETIMEDOUT. – fgsfdsfgts Sep 02 '17 at 21:53
  • I would have expected a later POSIX version: I believe 200809L is current, while 200012L and 199506L were two previous versions. These correspond to `_XOPEN_SOURCE` values of 700, 600, 500 respectively. – Jonathan Leffler Sep 02 '17 at 21:59
  • I would have expected a later POSIX version: I believe 200809L is current, while 200012L and 199506L were two previous versions. These correspond to `_XOPEN_SOURCE` values of 700, 600, 500 respectively. The 199309L value corresponds to POSIX before threads were part of the main standard (the 199506L value is for POSIX with threads in the main standard). – Jonathan Leffler Sep 02 '17 at 22:05

1 Answers1

12

You are using the wrong clock. The default clock used by pthread_cond_timedwait is CLOCK_REALTIME. If you really want to use CLOCK_MONOTONIC instead, you'll need to set the clock attribute of your condition variable:

pthread_condattr_t condattr;
pthread_condattr_init(&condattr);
pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
pthread_cond_init(&cond, &condattr);
Miles Budnek
  • 28,216
  • 2
  • 35
  • 52