11 static pthread_attr_t attributes
;
12 static int id
[4] = {0, 1, 2, 3};
13 static pthread_t tid
[4];
15 static bool blocking
[4];
16 static pthread_key_t self
;
24 sigsetjmp(env
, false);
29 sigdelset(&mask
, SIGUSR1
);
30 sigdelset(&mask
, SIGTERM
);
32 while (state
[*i
] == false && blocking
[*i
] == false)
40 suspendHandler(int sig
) {
41 int *i
= (int*)pthread_getspecific(self
);
52 act
.sa_handler
= suspendHandler
;
53 sigemptyset(&act
.sa_mask
);
55 sigaction(SIGUSR1
, &act
, NULL
);
58 sigaddset(&mask
, SIGQUIT
);
59 sigaddset(&mask
, SIGINT
);
60 sigaddset(&mask
, SIGPIPE
);
61 sigprocmask(SIG_BLOCK
, &mask
, NULL
);
73 sigaddset(&mask
, SIGUSR1
);
74 pthread_sigmask(SIG_BLOCK
, &mask
, NULL
);
76 printf("thread %d suspending\n", *i
);
80 printf("thread %d suspend ended\n", *i
);
82 pthread_sigmask(SIG_UNBLOCK
, &mask
, NULL
);
87 threadStart(void *arg
)
90 pthread_setspecific(self
, &i
);
95 printf("threadStart(%d)\n", i
);
97 for (int j
= 0; j
< 10; j
++) {
102 printf("quitting %d\n", i
);
110 for (int i = 0; i < 4; i++) {
112 if (state[i] == true)
113 pthread_kill(tid[i], SIGUSR1);
116 for (int i = 0; i < 4; i++) {
117 while(state[i] == true) {
128 for (int i
= 0; i
< 4; i
++) {
130 if (state
[i
] == false) {
131 printf("thread %d signaled for resume\n", i
);
132 pthread_kill(tid
[i
], SIGUSR1
);
137 for (int i
= 0; i
< 4; i
++) {
138 while(state
[i
] == false && t
-- > 0) {
139 printf("thread %d still suspended, yielding\n", i
);
147 main(int argc
, char **argv
)
151 pthread_key_create(&self
, NULL
);
153 pthread_attr_init(&attributes
);
154 pthread_attr_setdetachstate(&attributes
, PTHREAD_CREATE_DETACHED
);
156 for (int i
= 0; i
< 4; i
++) {
157 if (pthread_create(&tid
[i
], &attributes
, threadStart
, &id
[i
]) != 0)
158 fprintf(stderr
, "couldn't create thread %d\n", i
);
159 printf("thread %d created\n", i
);
162 /*suspendAllThreads();*/
163 printf("snoozing\n");
165 printf("resuming all threads\n");
167 printf("resuming all threads done\n");