kconfig: use pkg-config for ncurses detection
[akaros.git] / user / utest / pvcalarm.c
1 #include <utest/utest.h>
2 #include <pthread.h>
3 #include <parlib/pvcalarm.h>
4
5 TEST_SUITE("PVCALARMS");
6
7 /* <--- Begin definition of test cases ---> */
8 bool test_pvcalarms(void) {
9         const int INTERVAL = 10000;
10         const int ITERS = 100;
11         int count[max_vcores()];
12         void pvcalarm_callback()
13         {
14                 __sync_fetch_and_add(&count[vcore_id()], 1);
15         }
16
17         parlib_never_yield = TRUE;
18         pthread_mcp_init();
19         vcore_request_total(max_vcores());
20         parlib_never_vc_request = TRUE;
21         for (int i = 0; i < max_vcores(); i++)
22                 count[i] = 0;
23         
24         uint64_t now, then;
25         now = tsc2usec(read_tsc());
26         enable_pvcalarms(PVCALARM_PROF, INTERVAL, pvcalarm_callback);
27         for (int i = 0; i < max_vcores(); i++)
28                 while(count[i] < ITERS)
29                         cpu_relax();
30         disable_pvcalarms();
31         then = tsc2usec(read_tsc());
32
33         UT_ASSERT_M("Alarms finished too soon", then > (now + INTERVAL*ITERS));
34         UT_ASSERT_M("Alarms finished too late", then < (now +
35                                                         2*INTERVAL*ITERS));
36         return true;
37 }
38
39 bool test_sigperf(void)
40 {
41         const int INTERVAL = 10000;
42         const int ITERATIONS = 100;
43         const int NUM_PTHREADS = 10;
44         int count[NUM_PTHREADS];
45         pthread_t threads[NUM_PTHREADS];
46         static __thread int *__count;
47
48         void *thread_handler(void *arg)
49         {
50                 __count = (int*)arg;
51                 sigset_t s;
52                 sigemptyset(&s);
53                 sigaddset(&s, SIGPROF);
54                 pthread_sigmask(SIG_UNBLOCK, &s, NULL);
55                 int old_count = 0, new_count = 0;
56                 while(1) {
57                         while ((new_count = atomic_read((atomic_t)__count)) <=
58                               old_count);
59                         if (new_count >= ITERATIONS)
60                                 break;
61                         old_count = new_count;
62                         pthread_yield();
63                 }
64                 return 0;
65         }
66         void signal_handler(int signo)
67         {
68                 assert(signo == SIGPROF);
69                 __sync_fetch_and_add(__count, 1);
70         }
71
72         parlib_never_yield = FALSE;
73         parlib_never_vc_request = FALSE;
74
75         sigset_t s;
76         sigemptyset(&s);
77         sigaddset(&s, SIGPROF);
78         pthread_sigmask(SIG_BLOCK, &s, NULL);
79         struct sigaction sigact = {.sa_handler = signal_handler, 0};
80
81         sigaction(SIGPROF, &sigact, 0);
82         for (int i = 0; i < NUM_PTHREADS; i++)
83                 count[i] = 0;
84
85         enable_profalarm(INTERVAL);
86         for (int i = 0; i < NUM_PTHREADS; i++)
87                 pthread_create(&threads[i], NULL, thread_handler, &count[i]);
88
89         for (int i = 0; i < NUM_PTHREADS; i++)
90                 while (count[i] < ITERATIONS)
91                         cpu_relax();
92
93         disable_pvcalarms();
94         return true;
95 }
96
97 /* <--- End definition of test cases ---> */
98
99 struct utest utests[] = {
100         UTEST_REG(pvcalarms),
101         UTEST_REG(sigperf),
102 };
103 int num_utests = sizeof(utests) / sizeof(struct utest);
104
105 int main(int argc, char *argv[]) {
106         char **whitelist = &argv[1];
107         int whitelist_len = argc - 1;
108
109         RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
110 }