1 | #include <semaphore.h> |
---|---|
2 | #include <stdio.h> |
3 | #include <unistd.h> |
4 | #include <pthread.h> |
5 | #include <internaltypes.h> |
6 | |
7 | #ifndef SEM_WAIT |
8 | # define SEM_WAIT(s) sem_wait (s) |
9 | #endif |
10 | |
11 | static void * |
12 | tf (void *arg) |
13 | { |
14 | #ifdef PREPARE |
15 | PREPARE |
16 | #endif |
17 | SEM_WAIT (arg); |
18 | return NULL; |
19 | } |
20 | |
21 | int |
22 | main (void) |
23 | { |
24 | int tries = 5; |
25 | pthread_t th; |
26 | union |
27 | { |
28 | sem_t s; |
29 | struct new_sem ns; |
30 | } u; |
31 | again: |
32 | if (sem_init (sem: &u.s, pshared: 0, value: 0) != 0) |
33 | { |
34 | puts (s: "sem_init failed"); |
35 | return 1; |
36 | } |
37 | #if __HAVE_64B_ATOMICS |
38 | if ((u.ns.data >> SEM_NWAITERS_SHIFT) != 0) |
39 | #else |
40 | if (u.ns.nwaiters != 0) |
41 | #endif |
42 | { |
43 | puts (s: "nwaiters not initialized"); |
44 | return 1; |
45 | } |
46 | |
47 | if (pthread_create (newthread: &th, NULL, start_routine: tf, arg: &u.s) != 0) |
48 | { |
49 | puts (s: "pthread_create failed"); |
50 | return 1; |
51 | } |
52 | |
53 | sleep (seconds: 1); |
54 | |
55 | if (pthread_cancel (th: th) != 0) |
56 | { |
57 | puts (s: "pthread_cancel failed"); |
58 | return 1; |
59 | } |
60 | |
61 | void *r; |
62 | if (pthread_join (th: th, thread_return: &r) != 0) |
63 | { |
64 | puts (s: "pthread_join failed"); |
65 | return 1; |
66 | } |
67 | if (r != PTHREAD_CANCELED && --tries > 0) |
68 | { |
69 | /* Maybe we get the scheduling right the next time. */ |
70 | sem_destroy (sem: &u.s); |
71 | goto again; |
72 | } |
73 | |
74 | #if __HAVE_64B_ATOMICS |
75 | if ((u.ns.data >> SEM_NWAITERS_SHIFT) != 0) |
76 | #else |
77 | if (u.ns.nwaiters != 0) |
78 | #endif |
79 | { |
80 | puts (s: "nwaiters not reset"); |
81 | return 1; |
82 | } |
83 | |
84 | return 0; |
85 | } |
86 |