Rename EVENT_FALLBACK -> EVENT_SPAM_INDIR (XCC)
[akaros.git] / user / utest / pvcalarm.c
1 #include <utest/utest.h>
2 #include <pthread.h>
3 #include <benchutil/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         pthread_can_vcore_request(FALSE);
18         pthread_mcp_init();
19         vcore_request(max_vcores() - num_vcores());
20         for (int i=0; i<max_vcores(); i++)
21                 count[i] = 0;
22         
23         uint64_t now, then;
24         now = tsc2usec(read_tsc());
25         enable_pvcalarms(PVCALARM_PROF, INTERVAL, pvcalarm_callback);
26         for (int i=0; i<max_vcores(); i++)
27                 while(count[i] < ITERS)
28                         cpu_relax();
29         disable_pvcalarms();
30         then = tsc2usec(read_tsc());
31
32         UT_ASSERT_M("Alarms finished too soon", then > (now + INTERVAL*ITERS));
33         UT_ASSERT_M("Alarms finished too late", then < (now + 2*INTERVAL*ITERS));
34         return true;
35 }
36
37 bool test_sigperf(void)
38 {
39         const int INTERVAL = 10000;
40         const int ITERATIONS = 100;
41         const int NUM_PTHREADS = 10;
42         int count[NUM_PTHREADS];
43         pthread_t threads[NUM_PTHREADS];
44         static __thread int *__count;
45
46         void *thread_handler(void *arg)
47         {
48                 __count = (int*)arg;
49                 sigset_t s;
50                 sigemptyset(&s);
51                 sigaddset(&s, SIGPROF);
52                 pthread_sigmask(SIG_UNBLOCK, &s, NULL);
53                 int old_count = 0, new_count = 0;
54                 while(1) {
55                         while((new_count = atomic_read((atomic_t)__count)) <= old_count);
56                         if (new_count >= ITERATIONS) break;
57                         old_count = new_count;
58                         pthread_yield();
59                 }
60         }
61         void signal_handler(int signo)
62         {
63                 assert(signo == SIGPROF);
64                 __sync_fetch_and_add(__count, 1);
65         }
66
67         pthread_lib_init();
68         pthread_can_vcore_request(TRUE);
69
70         sigset_t s;
71         sigemptyset(&s);
72         sigaddset(&s, SIGPROF);
73         pthread_sigmask(SIG_BLOCK, &s, NULL);
74         struct sigaction sigact = {.sa_handler = signal_handler, 0};
75         sigaction(SIGPROF, &sigact, 0);
76         for (int i=0; i<NUM_PTHREADS; i++)
77                 count[i] = 0;
78
79         enable_profalarm(INTERVAL);
80         for (int i=0; i<NUM_PTHREADS; i++)
81                 pthread_create(&threads[i], NULL, thread_handler, &count[i]);
82
83         for (int i=0; i<NUM_PTHREADS; i++)
84                 while(count[i] < ITERATIONS)
85                         cpu_relax();
86
87         disable_pvcalarms();
88         return true;
89 }
90
91 /* <--- End definition of test cases ---> */
92
93 struct utest utests[] = {
94         UTEST_REG(pvcalarms),
95         UTEST_REG(sigperf),
96 };
97 int num_utests = sizeof(utests) / sizeof(struct utest);
98
99 int main(int argc, char *argv[]) {
100         // Run test suite passing it all the args as whitelist of what tests to run.
101         char **whitelist = &argv[1];
102         int whitelist_len = argc - 1;
103         RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
104 }