|
Szabolcs Nagy |
453836 |
/* unnamed semaphore sanity check */
|
|
Szabolcs Nagy |
453836 |
#include <pthread.h>
|
|
Szabolcs Nagy |
453836 |
#include <semaphore.h>
|
|
Szabolcs Nagy |
453836 |
#include <time.h>
|
|
Szabolcs Nagy |
453836 |
#include <string.h>
|
|
Szabolcs Nagy |
453836 |
#include <errno.h>
|
|
Szabolcs Nagy |
453836 |
#include "test.h"
|
|
Szabolcs Nagy |
453836 |
|
|
Szabolcs Nagy |
453836 |
#define T(f) if(f) t_error(#f" failed: %s\n", strerror(errno))
|
|
Szabolcs Nagy |
453836 |
#define T2(r,f) if((r=(f))) t_error(#f" failed: %s\n", strerror(r))
|
|
Szabolcs Nagy |
453836 |
|
|
Szabolcs Nagy |
453836 |
static void *start(void *arg)
|
|
Szabolcs Nagy |
453836 |
{
|
|
Szabolcs Nagy |
453836 |
struct timespec ts;
|
|
Szabolcs Nagy |
453836 |
sem_t *s = arg;
|
|
Szabolcs Nagy |
453836 |
T(clock_gettime(CLOCK_REALTIME, &ts);;
|
|
Szabolcs Nagy |
453836 |
ts.tv_sec += 1;
|
|
Szabolcs Nagy |
453836 |
T(sem_post(s));
|
|
Szabolcs Nagy |
453836 |
T(sem_timedwait(s+1, &ts);;
|
|
Szabolcs Nagy |
453836 |
return 0;
|
|
Szabolcs Nagy |
453836 |
}
|
|
Szabolcs Nagy |
453836 |
|
|
Szabolcs Nagy |
453836 |
static void many_waiters()
|
|
Szabolcs Nagy |
453836 |
{
|
|
Szabolcs Nagy |
453836 |
pthread_t t[3];
|
|
Szabolcs Nagy |
453836 |
sem_t s[2];
|
|
Szabolcs Nagy |
453836 |
int r;
|
|
Szabolcs Nagy |
453836 |
void *p;
|
|
Szabolcs Nagy |
453836 |
|
|
Szabolcs Nagy |
453836 |
T(sem_init(s, 0, 0));
|
|
Szabolcs Nagy |
453836 |
T(sem_init(s+1, 0, 0));
|
|
Szabolcs Nagy |
453836 |
T2(r,pthread_create(t, 0, start, s));
|
|
Szabolcs Nagy |
453836 |
T2(r,pthread_create(t+1, 0, start, s));
|
|
Szabolcs Nagy |
453836 |
T2(r,pthread_create(t+2, 0, start, s));
|
|
Szabolcs Nagy |
453836 |
T(sem_wait(s));
|
|
Szabolcs Nagy |
453836 |
T(sem_wait(s));
|
|
Szabolcs Nagy |
453836 |
T(sem_wait(s));
|
|
Szabolcs Nagy |
453836 |
T(sem_getvalue(s, &r);;
|
|
Szabolcs Nagy |
453836 |
if (r)
|
|
Szabolcs Nagy |
453836 |
t_error("sem value should be 0, got %d\n", r);
|
|
Szabolcs Nagy |
453836 |
T(sem_post(s+1));
|
|
Szabolcs Nagy |
453836 |
T(sem_post(s+1));
|
|
Szabolcs Nagy |
453836 |
T(sem_post(s+1));
|
|
Szabolcs Nagy |
453836 |
T2(r,pthread_join(t[0],&p);;
|
|
Szabolcs Nagy |
453836 |
T2(r,pthread_join(t[1],&p);;
|
|
Szabolcs Nagy |
453836 |
T2(r,pthread_join(t[2],&p);;
|
|
Szabolcs Nagy |
453836 |
T(sem_getvalue(s+1, &r);;
|
|
Szabolcs Nagy |
453836 |
if (r)
|
|
Szabolcs Nagy |
453836 |
t_error("sem value should be 0, got %d\n", r);
|
|
Szabolcs Nagy |
453836 |
T(sem_destroy(s));
|
|
Szabolcs Nagy |
453836 |
T(sem_destroy(s+1));
|
|
Szabolcs Nagy |
453836 |
}
|
|
Szabolcs Nagy |
453836 |
|
|
Szabolcs Nagy |
453836 |
static void single_thread()
|
|
Szabolcs Nagy |
453836 |
{
|
|
Szabolcs Nagy |
453836 |
struct timespec ts;
|
|
Szabolcs Nagy |
453836 |
sem_t s;
|
|
Szabolcs Nagy |
453836 |
int r;
|
|
Szabolcs Nagy |
453836 |
|
|
Szabolcs Nagy |
453836 |
T(sem_init(&s, 0, 1));
|
|
Szabolcs Nagy |
453836 |
T(sem_wait(&s);;
|
|
Szabolcs Nagy |
453836 |
T(sem_getvalue(&s, &r);;
|
|
Szabolcs Nagy |
453836 |
if (r)
|
|
Szabolcs Nagy |
453836 |
t_error("sem value should be 0, got %d\n", r);
|
|
Szabolcs Nagy |
453836 |
if (sem_trywait(&s) != -1 || errno != EAGAIN)
|
|
Szabolcs Nagy |
453836 |
t_error("sem_trywait should fail with EAGAIN, got %s\n", strerror(errno));
|
|
Szabolcs Nagy |
453836 |
errno = 0;
|
|
Szabolcs Nagy |
453836 |
T(clock_gettime(CLOCK_REALTIME, &ts);;
|
|
Szabolcs Nagy |
453836 |
if (sem_timedwait(&s, &ts)!=-1 || errno != ETIMEDOUT)
|
|
Szabolcs Nagy |
453836 |
t_error("sem_timedwait should fail with ETIMEDOUT, got %s\n", strerror(errno));
|
|
Szabolcs Nagy |
453836 |
T(sem_destroy(&s);;
|
|
Szabolcs Nagy |
453836 |
}
|
|
Szabolcs Nagy |
453836 |
|
|
Szabolcs Nagy |
453836 |
int main(void)
|
|
Szabolcs Nagy |
453836 |
{
|
|
Szabolcs Nagy |
453836 |
single_thread();
|
|
Szabolcs Nagy |
453836 |
many_waiters();
|
|
Szabolcs Nagy |
453836 |
return t_status;
|
|
Szabolcs Nagy |
453836 |
}
|