Show inlined functions with bt-akaros.sh (kernel)
[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 <unistd.h>
9 #include <parlib/parlib.h>
10 #include <pthread.h>
11 #include <futex.h>
12 #include <signal.h>
13
14 // Signal handler run in vcore context which redirects signals to userspace by
15 // waking a thread waiting on a futex. Note, this does not guarantee that every
16 // signal that comes through this handler will be noticed or processed by the
17 // thread.
18 int __sigpending = 0;
19 void sig_handler(int signr)
20 {
21         __sigpending = 1;
22         futex(&__sigpending, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
23 }
24
25 // User level thread waiting on a futex to count signals
26 int count = 0;
27 void *count_signals(void *arg)
28 {
29         while(1) {
30                 futex(&__sigpending, FUTEX_WAIT, 0, NULL, NULL, 0);
31                 __sync_fetch_and_add(&count, 1);
32                 __sigpending = 0;
33         }
34 }
35
36 // Thread spamming us with signals
37 void *sig_thread(void *arg)
38 {
39         int *done = (int*)arg;
40         struct sigaction sigact = {.sa_handler = sig_handler, 0};
41
42         sigaction(SIGUSR1, &sigact, 0);
43         while(1) {
44                 kill(getpid(), SIGUSR1);
45                 cmb();
46                 if (*done) return NULL;
47         }
48 }
49
50 int main(int argc, char **argv)
51 {
52         int done = false;
53
54         pthread_t pth_handle, pth_handle2;
55         // Spawn off a thread to spam us with signals
56         pthread_create(&pth_handle, NULL, &sig_thread, &done);
57         // Spawn off a thread to process those signals
58         pthread_create(&pth_handle2, NULL, &count_signals, NULL);
59
60         // Sleep for 3 seconds by timing out on a futex
61         int dummy = 0;
62         struct timespec timeout = {.tv_sec = 3, 0};
63
64         futex(&dummy, FUTEX_WAIT, 0, &timeout, NULL, 0);
65         // Force the signal tread to exit
66         cmb();
67         done = true;
68         pthread_join(pth_handle, NULL);
69         printf("count: %d\n", count);
70         return 0;
71 }