• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
start(void * arg)12 static 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 
many_waiters()23 static 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 
single_thread()54 static 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 
main(void)74 int main(void)
75 {
76 	single_thread();
77 	many_waiters();
78 	return t_status;
79 }
80