OSDI Microbenchmarks
[akaros.git] / tests / msr_get_singlecore.c
1 /* tests/msr_get_singlecore.c
2  *
3  * Like msr_get_cores.c, but it only gets one core. */
4
5
6 #include <parlib.h>
7 #include <ros/mman.h>
8 #include <ros/resource.h>
9 #include <ros/procdata.h>
10 #include <ros/notification.h>
11 #include <ros/bcq.h>
12 #include <arch/arch.h>
13 #include <rstdio.h>
14 #include <vcore.h>
15 #include <mcs.h>
16 #include <timing.h>
17 #include <rassert.h>
18
19 mcs_barrier_t b;
20
21 void *core0_tls = 0;
22 uint64_t begin = 0, end = 0;
23 volatile bool core1_up = FALSE;
24
25 int main(int argc, char** argv)
26 {
27         uint32_t vcoreid = vcore_id();
28         int retval = 0;
29
30         mcs_barrier_init(&b, max_vcores());
31
32 /* begin: stuff userspace needs to do before switching to multi-mode */
33         if (vcore_init())
34                 printf("vcore_init() failed, we're fucked!\n");
35         /* tell the kernel where and how we want to receive notifications */
36         struct notif_method *nm;
37         for (int i = 0; i < MAX_NR_NOTIF; i++) {
38                 nm = &__procdata.notif_methods[i];
39                 nm->flags |= NOTIF_WANTED | NOTIF_MSG | NOTIF_IPI;
40                 nm->vcoreid = i % 2; // vcore0 or 1, keepin' it fresh.
41         }
42         /* Need to save this somewhere that you can find it again when restarting
43          * core0 */
44         core0_tls = get_tls_desc(0);
45         /* Need to save our floating point state somewhere (like in the
46          * user_thread_tcb so it can be restarted too */
47         /* don't forget to enable notifs on vcore0 at some point */
48         struct preempt_data *vcpd;
49         vcpd = &__procdata.vcore_preempt_data[0];
50         vcpd->notif_enabled = TRUE;
51 /* end: stuff userspace needs to do before switching to multi-mode */
52
53         /* get into multi mode */
54         retval = vcore_request(1);
55         if (retval)
56                 printf("Fucked!\n");
57
58         printf("Proc %d requesting another vcore\n", getpid());
59         begin = read_tsc();
60         retval = vcore_request(1);
61         if (retval)
62                 printf("Fucked!\n");
63         while (!core1_up)
64                 cpu_relax;
65         end = read_tsc();
66         printf("Took %llu usec (%llu nsec) to receive 1 core (cold).\n",
67                udiff(begin, end), ndiff(begin, end));
68         printf("[T]:002:%llu:%llu:1:C.\n",
69                udiff(begin, end), ndiff(begin, end));
70         core1_up = FALSE;
71         udelay(2000000);
72         printf("Proc %d requesting the vcore again\n", getpid());
73         begin = read_tsc();
74         retval = vcore_request(1);
75         if (retval)
76                 printf("Fucked!\n");
77         while (!core1_up)
78                 cpu_relax();
79         end = read_tsc();
80         printf("Took %llu usec (%llu nsec) to receive 1 core (warm).\n",
81                udiff(begin, end), ndiff(begin, end));
82         printf("[T]:002:%llu:%llu:1:W.\n",
83                udiff(begin, end), ndiff(begin, end));
84         return 0;
85 }
86
87 void vcore_entry(void)
88 {
89         uint32_t vcoreid = vcore_id();
90
91 /* begin: stuff userspace needs to do to handle notifications */
92         struct vcore *vc = &__procinfo.vcoremap[vcoreid];
93         struct preempt_data *vcpd;
94         vcpd = &__procdata.vcore_preempt_data[vcoreid];
95         
96         /* Lets try to restart vcore0's context.  Note this doesn't do anything to
97          * set the appropriate TLS.  On x86, this will involve changing the LDT
98          * entry for this vcore to point to the TCB of the new user-thread. */
99         if (vcoreid == 0) {
100                 vcpd->notif_pending = 0;
101                 set_tls_desc(core0_tls, 0);
102                 /* Load silly state (Floating point) too */
103                 pop_ros_tf(&vcpd->notif_tf, vcoreid);
104                 panic("should never see me!");
105         }       
106 /* end: stuff userspace needs to do to handle notifications */
107
108         /* all other vcores are down here */
109         core1_up = TRUE;
110
111         while (core1_up)
112                 cpu_relax();
113         printf("Proc %d's vcore %d is yielding\n", getpid(), vcoreid);
114         sys_yield(0);
115
116         while(1);
117 }
118