As a bonus, both threads check if they slept for over a millisecond more than they should.
/*
* cc -mt -lpthread timer.c -o timer -O3
*/
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <err.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/types.h>
#define SECOND (1000000000)
#define MILISEC (1000000)
pthread_cond_t cv;
pthread_mutex_t mutex;
struct timespec ts = { 1 , 0 };
static void
check_hrt(hrtime_t hrt, char *str)
{
hrtime_t delta = gethrtime() - hrt;
if ((delta - SECOND) >= MILISEC) {
(void) fprintf(stderr, "[%s] %lu ns (!!!)\n", str, delta);
} else {
(void) fprintf(stderr, "[%s] %lu ns\n", str, delta);
}
}
void *
wait_thread(void *arg)
{
hrtime_t hrt, delta;
int ret;
for (;;) {
pthread_mutex_lock(&mutex);
hrt = gethrtime();
ret = pthread_cond_wait(&cv, &mutex);
if (ret != 0 && ret != ETIMEDOUT) {
errno = ret;
perror("[wait] condwait timed out");
}
pthread_mutex_unlock(&mutex);
check_hrt(hrt, "wait");
}
}
void *
signal_thread(void *arg)
{
hrtime_t hrt, delta;
for (;;) {
hrt = gethrtime();
nanosleep(&ts, NULL);
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
check_hrt(hrt, "sign");
}
}
int
main(int argc, char **argv)
{
pthread_t waiter, signaler;
pthread_cond_init(&cv, NULL);
pthread_mutex_init(&mutex, NULL);
if (pthread_create(&waiter, NULL, wait_thread, NULL) != 0) {
perror("failed to create waiter thread");
return (1);
}
if (pthread_create(&signaler, NULL, signal_thread, NULL) != 0) {
perror("failed to create signaler thread");
return (1);
}
pthread_join(waiter, NULL);
pthread_join(signaler, NULL);
return (0);
}
No comments:
Post a Comment