1/* unnamed semaphore sanity check */ 2#include <pthread.h> 3#include <semaphore.h> 4#include <time.h> 5#include <string.h> 6#include <errno.h> 7#include "test.h" 8 9#define T(f) if(f) t_error(#f" failed: %s\n", strerror(errno)) 10#define T2(r,f) if((r=(f))) t_error(#f" failed: %s\n", strerror(r)) 11 12static void *start(void *arg) 13{ 14 struct timespec ts; 15 sem_t *s = arg; 16 T(clock_gettime(CLOCK_REALTIME, &ts)); 17 ts.tv_sec += 1; 18 T(sem_post(s)); 19 T(sem_timedwait(s+1, &ts)); 20 return 0; 21} 22 23static void many_waiters() 24{ 25 pthread_t t[3]; 26 sem_t s[2]; 27 int r; 28 void *p; 29 30 T(sem_init(s, 0, 0)); 31 T(sem_init(s+1, 0, 0)); 32 T2(r,pthread_create(t, 0, start, s)); 33 T2(r,pthread_create(t+1, 0, start, s)); 34 T2(r,pthread_create(t+2, 0, start, s)); 35 T(sem_wait(s)); 36 T(sem_wait(s)); 37 T(sem_wait(s)); 38 T(sem_getvalue(s, &r)); 39 if (r) 40 t_error("sem value should be 0, got %d\n", r); 41 T(sem_post(s+1)); 42 T(sem_post(s+1)); 43 T(sem_post(s+1)); 44 T2(r,pthread_join(t[0],&p)); 45 T2(r,pthread_join(t[1],&p)); 46 T2(r,pthread_join(t[2],&p)); 47 T(sem_getvalue(s+1, &r)); 48 if (r) 49 t_error("sem value should be 0, got %d\n", r); 50 T(sem_destroy(s)); 51 T(sem_destroy(s+1)); 52} 53 54static void single_thread() 55{ 56 struct timespec ts; 57 sem_t s; 58 int r; 59 60 T(sem_init(&s, 0, 1)); 61 T(sem_wait(&s)); 62 T(sem_getvalue(&s, &r)); 63 if (r) 64 t_error("sem value should be 0, got %d\n", r); 65 if (sem_trywait(&s) != -1 || errno != EAGAIN) 66 t_error("sem_trywait should fail with EAGAIN, got %s\n", strerror(errno)); 67 errno = 0; 68 T(clock_gettime(CLOCK_REALTIME, &ts)); 69 if (sem_timedwait(&s, &ts)!=-1 || errno != ETIMEDOUT) 70 t_error("sem_timedwait should fail with ETIMEDOUT, got %s\n", strerror(errno)); 71 T(sem_destroy(&s)); 72} 73 74int main(void) 75{ 76 single_thread(); 77 many_waiters(); 78 return t_status; 79} 80