Adds kill to the monitor
[akaros.git] / tests / signal_futex.c
1 /* Copyright (c) 2014 The Regents of the University of California
2  * Kevin Klues <klueska@cs.berkeley.edu>
3  * See LICENSE for details.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <parlib.h>
9 #include <pthread.h>
10 #include <futex.h>
11 #include <signal.h>
12
13 // Signal handler run in vcore context which redirects signals to userspace by
14 // waking a thread waiting on a futex. Note, this does not guarantee that every
15 // signal that comes through this handler will be noticed or processed by the
16 // thread.
17 int __sigpending = 0;
18 void sig_handler(int signr) {
19         __sigpending = 1;
20         futex(&__sigpending, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
21 }
22
23 // User level thread waiting on a futex to count signals
24 int count = 0;
25 void *count_signals(void *arg) {
26         while(1) {
27                 futex(&__sigpending, FUTEX_WAIT, 0, NULL, NULL, 0);
28                 __sync_fetch_and_add(&count, 1);
29                 __sigpending = 0;
30         }
31 }
32
33 // Thread spamming us with signals
34 void *sig_thread(void *arg) {
35         int *done = (int*)arg;
36         struct sigaction sigact = {.sa_handler = sig_handler, 0};
37         sigaction(SIGUSR1, &sigact, 0);
38         while(1) {
39                 kill(getpid(), SIGUSR1);
40                 cmb();
41                 if (*done) return NULL;
42         }
43 }
44
45 int main(int argc, char **argv)
46 {
47         int done = false;
48         pthread_t pth_handle, pth_handle2;
49         // Spawn off a thread to spam us with signals
50         pthread_create(&pth_handle, NULL, &sig_thread, &done);
51         // Spawn off a thread to process those signals
52         pthread_create(&pth_handle2, NULL, &count_signals, NULL);
53         // Sleep for 3 seconds by timing out on a futex
54         int dummy = 0;
55         struct timespec timeout = {.tv_sec = 3, 0};
56         futex(&dummy, FUTEX_WAIT, 0, &timeout, NULL, 0);
57         // Force the signal tread to exit
58         cmb();
59         done = true;
60         pthread_join(pth_handle, NULL);
61         printf("count: %d\n", count);
62         return 0;
63 }