1// USAGE: gcc -g3 -o choose choose.c -pthread
2
3#include <pthread.h>
4#include <semaphore.h>
5#include <stdio.h>
6
7#define CHOOSE_ARG 3
8
9pthread_mutex_t mut_choose = PTHREAD_MUTEX_INITIALIZER;
10sem_t sem_choose_out;
11sem_t sem_choose_in;
12
13// Shared variable: protected by the mut_choose mutex.
14int choose_arg_retvalue;
15
16void *choose_helper_thread(void *notused) {
17 int choose_arg;
18
19 while (1) {
20 // Get argument of choose
21 sem_wait(&sem_choose_out);
22
23 pthread_mutex_lock(&mut_choose);
24 choose_arg = choose_arg_retvalue;
25 pthread_mutex_unlock(&mut_choose);
26
27printf("choose(%d) received %d.\n", CHOOSE_ARG, choose_arg);
28
29 sem_post(&sem_choose_in);
30
31 choose_arg_retvalue = 0;
32 for (int i = 1; i < choose_arg; i++) {
33 pthread_mutex_lock(&mut_choose);
34 choose_arg_retvalue = i;
35 pthread_mutex_unlock(&mut_choose);
36 }
37
38 sem_post(&sem_choose_in);
39 }
40 return NULL;
41}
42
43int choose(int choose_arg) {
44 pthread_mutex_lock(&mut_choose);
45 choose_arg_retvalue = choose_arg;
46 pthread_mutex_unlock(&mut_choose);
47
48 sem_post(&sem_choose_out);
49 sem_wait(&sem_choose_in);
50
51 int choose_retvalue = -1;
52 pthread_mutex_lock(&mut_choose);
53 choose_retvalue = choose_arg_retvalue;
54 pthread_mutex_unlock(&mut_choose);
55
56 sem_wait(&sem_choose_in);
57 return choose_retvalue;
58}
59
60int main() {
61 pthread_t choose_thread;
62 sem_init(&sem_choose_in, 0, 0);
63 sem_init(&sem_choose_out, 0, 0);
64#if 1
65 pthread_mutex_init(&mut_choose, NULL);
66#endif
67 pthread_create(&choose_thread, NULL, &choose_helper_thread, NULL);
68
69#if 0
70 pthread_mutex_lock(&mut_choose);
71 pthread_mutex_unlock(&mut_choose);
72#endif
73
74 int choose_retvalue = choose(3);
75
76 printf("choose(%d) returned %d.\n", CHOOSE_ARG, choose_retvalue);
77 return 0;
78}