1570af302Sopenharmony_ci/* unnamed semaphore sanity check */ 2570af302Sopenharmony_ci#include <pthread.h> 3570af302Sopenharmony_ci#include <semaphore.h> 4570af302Sopenharmony_ci#include <time.h> 5570af302Sopenharmony_ci#include <string.h> 6570af302Sopenharmony_ci#include <errno.h> 7570af302Sopenharmony_ci#include "test.h" 8570af302Sopenharmony_ci 9570af302Sopenharmony_ci#define T(f) if(f) t_error(#f" failed: %s\n", strerror(errno)) 10570af302Sopenharmony_ci#define T2(r,f) if((r=(f))) t_error(#f" failed: %s\n", strerror(r)) 11570af302Sopenharmony_ci 12570af302Sopenharmony_cistatic void *start(void *arg) 13570af302Sopenharmony_ci{ 14570af302Sopenharmony_ci struct timespec ts; 15570af302Sopenharmony_ci sem_t *s = arg; 16570af302Sopenharmony_ci T(clock_gettime(CLOCK_REALTIME, &ts)); 17570af302Sopenharmony_ci ts.tv_sec += 1; 18570af302Sopenharmony_ci T(sem_post(s)); 19570af302Sopenharmony_ci T(sem_timedwait(s+1, &ts)); 20570af302Sopenharmony_ci return 0; 21570af302Sopenharmony_ci} 22570af302Sopenharmony_ci 23570af302Sopenharmony_cistatic void many_waiters() 24570af302Sopenharmony_ci{ 25570af302Sopenharmony_ci pthread_t t[3]; 26570af302Sopenharmony_ci sem_t s[2]; 27570af302Sopenharmony_ci int r; 28570af302Sopenharmony_ci void *p; 29570af302Sopenharmony_ci 30570af302Sopenharmony_ci T(sem_init(s, 0, 0)); 31570af302Sopenharmony_ci T(sem_init(s+1, 0, 0)); 32570af302Sopenharmony_ci T2(r,pthread_create(t, 0, start, s)); 33570af302Sopenharmony_ci T2(r,pthread_create(t+1, 0, start, s)); 34570af302Sopenharmony_ci T2(r,pthread_create(t+2, 0, start, s)); 35570af302Sopenharmony_ci T(sem_wait(s)); 36570af302Sopenharmony_ci T(sem_wait(s)); 37570af302Sopenharmony_ci T(sem_wait(s)); 38570af302Sopenharmony_ci T(sem_getvalue(s, &r)); 39570af302Sopenharmony_ci if (r) 40570af302Sopenharmony_ci t_error("sem value should be 0, got %d\n", r); 41570af302Sopenharmony_ci T(sem_post(s+1)); 42570af302Sopenharmony_ci T(sem_post(s+1)); 43570af302Sopenharmony_ci T(sem_post(s+1)); 44570af302Sopenharmony_ci T2(r,pthread_join(t[0],&p)); 45570af302Sopenharmony_ci T2(r,pthread_join(t[1],&p)); 46570af302Sopenharmony_ci T2(r,pthread_join(t[2],&p)); 47570af302Sopenharmony_ci T(sem_getvalue(s+1, &r)); 48570af302Sopenharmony_ci if (r) 49570af302Sopenharmony_ci t_error("sem value should be 0, got %d\n", r); 50570af302Sopenharmony_ci T(sem_destroy(s)); 51570af302Sopenharmony_ci T(sem_destroy(s+1)); 52570af302Sopenharmony_ci} 53570af302Sopenharmony_ci 54570af302Sopenharmony_cistatic void single_thread() 55570af302Sopenharmony_ci{ 56570af302Sopenharmony_ci struct timespec ts; 57570af302Sopenharmony_ci sem_t s; 58570af302Sopenharmony_ci int r; 59570af302Sopenharmony_ci 60570af302Sopenharmony_ci T(sem_init(&s, 0, 1)); 61570af302Sopenharmony_ci T(sem_wait(&s)); 62570af302Sopenharmony_ci T(sem_getvalue(&s, &r)); 63570af302Sopenharmony_ci if (r) 64570af302Sopenharmony_ci t_error("sem value should be 0, got %d\n", r); 65570af302Sopenharmony_ci if (sem_trywait(&s) != -1 || errno != EAGAIN) 66570af302Sopenharmony_ci t_error("sem_trywait should fail with EAGAIN, got %s\n", strerror(errno)); 67570af302Sopenharmony_ci errno = 0; 68570af302Sopenharmony_ci T(clock_gettime(CLOCK_REALTIME, &ts)); 69570af302Sopenharmony_ci if (sem_timedwait(&s, &ts)!=-1 || errno != ETIMEDOUT) 70570af302Sopenharmony_ci t_error("sem_timedwait should fail with ETIMEDOUT, got %s\n", strerror(errno)); 71570af302Sopenharmony_ci T(sem_destroy(&s)); 72570af302Sopenharmony_ci} 73570af302Sopenharmony_ci 74570af302Sopenharmony_ciint main(void) 75570af302Sopenharmony_ci{ 76570af302Sopenharmony_ci single_thread(); 77570af302Sopenharmony_ci many_waiters(); 78570af302Sopenharmony_ci return t_status; 79570af302Sopenharmony_ci} 80