this repo has no description
1// mach_semaphore.c
2
3#include <stdio.h>
4#include <unistd.h>
5#include <stdlib.h>
6#include <pthread.h>
7#include <mach/mach.h>
8
9#define OUT_ON_MACH_ERROR(msg, retval) \
10 if (kr != KERN_SUCCESS) { mach_error(msg ":" , kr); goto out; }
11
12#define PTHID() (unsigned long)(pthread_self())
13
14#define SEMAPHORE_WAIT(s, n) \
15 { int i; for (i = 0; i < (n); i++) { semaphore_wait((s)); } }
16
17semaphore_t g_sem[2];
18
19void *
20start_routine(void *id)
21{
22 semaphore_signal(g_sem[1]);
23 fprintf(stderr, "thread: %lx about to decrement semaphore count\n", id);
24 semaphore_wait(g_sem[0]);
25 fprintf(stderr, "thread: %lx succeeded in decrementing semaphore count\n", id);
26 semaphore_signal(g_sem[1]);
27 return NULL;
28}
29
30int
31main(void)
32{
33 pthread_t pthread1, pthread2, pthread3;
34 semaphore_t* sem = g_sem;
35 kern_return_t kr;
36
37 setbuf(stdout, NULL);
38
39 kr = semaphore_create(mach_task_self(), &sem[0], SYNC_POLICY_FIFO, 0);
40 OUT_ON_MACH_ERROR("semaphore_create", kr);
41
42 kr = semaphore_create(mach_task_self(), &sem[1], SYNC_POLICY_FIFO, 0);
43 OUT_ON_MACH_ERROR("semaphore_create", kr);
44
45 (void)pthread_create(&pthread1, (const pthread_attr_t *)0,
46 start_routine, (void *) 0);
47 printf("created thread1=%lx\n", 0);
48
49 (void)pthread_create(&pthread2, (const pthread_attr_t *)0,
50 start_routine, (void *) 1);
51 printf("created thread2=%lx\n", 1);
52
53 (void)pthread_create(&pthread3, (const pthread_attr_t *)0,
54 start_routine, (void *) 2);
55 printf("created thread3=%lx\n", 2);
56
57 // wait until all three threads are ready
58 SEMAPHORE_WAIT(sem[1], 3);
59
60// printf("main: about to signal thread3\n");
61// semaphore_signal_thread(sem[0], pthread_mach_thread_np(pthread3));
62
63 // wait for thread3 to sem_signal()
64// semaphore_wait(sem[1]);
65
66 sleep(1);
67 printf("main: about to signal all threads\n");
68 semaphore_signal_all(sem[0]);
69
70 // wait for thread1 and thread2 to sem_signal()
71 SEMAPHORE_WAIT(sem[1], 3);
72
73out:
74 if (sem[0])
75 semaphore_destroy(mach_task_self(), sem[0]);
76 if (sem[1])
77 semaphore_destroy(mach_task_self(), sem[1]);
78
79 exit(kr);
80}
81