A utest for the pvcalarm service
[akaros.git] / user / utest / pvcalarm.c
1 #include <utest.h>
2 #include <vcore.h>
3 #include <uthread.h>
4 #include <event.h>
5 #include <pvcalarm.h>
6
7 TEST_SUITE("PVCALARMS");
8
9 void pvcalarm_vcore_entry()
10 {
11         uint32_t vcoreid= vcore_id();
12
13         /* Poke the pvcalarm to see if we need to enable it. */
14         /* This function is only non-null if the pvcalarm service is enabled */
15         if (vcore_poke_pvcalarm)
16                 vcore_poke_pvcalarm();
17
18         /* Drop back into main thread  for core 0 */
19         if (current_uthread) {
20                 assert(vcoreid == 0);
21                 run_current_uthread();
22         }
23
24         /* Other vcores get here, so enable notifs so they can get their alarm
25          * events */
26         enable_notifs(vcoreid);
27         while(1);
28 }
29 struct schedule_ops pvcalarm_sched_ops = {
30         .sched_entry = pvcalarm_vcore_entry,
31 };
32 struct schedule_ops *sched_ops = &pvcalarm_sched_ops;
33
34 /* <--- Begin definition of test cases ---> */
35 bool test_pvcalarms(void) {
36         const int INTERVAL = 10000;
37         const int ITERATIONS = 100;
38         int count[max_vcores() - num_vcores()];
39         void pvcalarm_callback()
40         {
41                 __sync_fetch_and_add(&count[vcore_id()], 1);
42         }
43
44         struct uthread dummy = {0};
45         uthread_lib_init(&dummy);
46         vcore_request(max_vcores() - num_vcores());
47         
48         uint64_t now, then;
49         now = tsc2usec(read_tsc());
50         enable_pvcalarms(PVCALARM_PROF, INTERVAL, pvcalarm_callback);
51         for (int i=0; i<num_vcores(); i++)
52                 while(count[i] < ITERATIONS)
53                         cpu_relax();
54         then = tsc2usec(read_tsc());
55         disable_pvcalarms();
56         UT_ASSERT_M("Alarms finished too soon", then > (now + INTERVAL*count[0]));
57         UT_ASSERT_M("Alarms finished too late", then < (now + 2*INTERVAL*count[0]));
58         return true;
59 }
60
61 /* <--- End definition of test cases ---> */
62
63 struct utest utests[] = {
64         UTEST_REG(pvcalarms),
65 };
66 int num_utests = sizeof(utests) / sizeof(struct utest);
67
68 int main(int argc, char *argv[]) {
69         // Run test suite passing it all the args as whitelist of what tests to run.
70         char **whitelist = &argv[1];
71         int whitelist_len = argc - 1;
72         RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
73 }