Adds test program to fetch a web page
[akaros.git] / tests / msr_get_cores.c
1 /* tests/msr_get_cores.c
2  *
3  * This measures the time it takes to request and receive the max_vcores() in
4  * the system.  The clock starts before vcore_request(), which includes the time
5  * it takes to allocate transition stacks and TLS.  The clock stops after
6  * barriering in vcore_entry(), while vcore0 gets restarted and barriers.  You
7  * really want to restart vcore0's context so it releases the lock in
8  * vcore_request().
9  *
10  * This will measure both the hot and cold times, with the hot times not needing
11  * to have stacks mmaped and other things. */
12
13
14 #include <parlib.h>
15 #include <ros/mman.h>
16 #include <ros/resource.h>
17 #include <ros/procdata.h>
18 #include <ros/bcq.h>
19 #include <arch/arch.h>
20 #include <stdio.h>
21 #include <vcore.h>
22 #include <mcs.h>
23 #include <timing.h>
24 #include <rassert.h>
25 #include <uthread.h>
26 #include <event.h>
27
28 mcs_barrier_t b;
29
30 void *core0_tls = 0;
31 uint64_t begin = 0, end = 0;
32
33 int main(int argc, char** argv)
34 {
35         uint32_t vcoreid = vcore_id();
36         int retval = 0;
37
38         mcs_barrier_init(&b, max_vcores());
39
40 /* begin: stuff userspace needs to do before switching to multi-mode */
41         vcore_init();
42         #if 0
43         /* tell the kernel where and how we want to receive notifications */
44         struct notif_method *nm;
45         for (int i = 0; i < MAX_NR_NOTIF; i++) {
46                 nm = &__procdata.notif_methods[i];
47                 nm->flags |= NOTIF_WANTED | NOTIF_MSG | NOTIF_IPI;
48                 nm->vcoreid = i % 2; // vcore0 or 1, keepin' it fresh.
49         }
50         #endif
51         /* Need to save this somewhere that you can find it again when restarting
52          * core0 */
53         core0_tls = get_tls_desc(0);
54         /* Need to save our floating point state somewhere (like in the
55          * user_thread_tcb so it can be restarted too */
56 /* end: stuff userspace needs to do before switching to multi-mode */
57
58         begin = read_tsc();
59         retval = vcore_request(max_vcores());
60         if (retval)
61                 printf("Fucked!\n");
62         mcs_barrier_wait(&b, vcoreid);
63         end = read_tsc();
64
65         printf("Took %llu usec (%llu nsec) to receive %d cores (cold).\n",
66                udiff(begin, end), ndiff(begin, end), max_vcores());
67         printf("[T]:001:%llu:%llu:%d:C.\n",
68                udiff(begin, end), ndiff(begin, end), max_vcores());
69         udelay(5000000);
70         begin = read_tsc();
71         retval = vcore_request(max_vcores() - 1);
72         if (retval)
73                 printf("Fucked!\n");
74         mcs_barrier_wait(&b, vcoreid);
75         end = read_tsc();
76         printf("Took %llu usec (%llu nsec) to receive %d cores (warm).\n",
77                udiff(begin, end), ndiff(begin, end), max_vcores());
78         printf("[T]:001:%llu:%llu:%d:W.\n",
79                udiff(begin, end), ndiff(begin, end), max_vcores());
80
81         return 0;
82 }
83
84 void vcore_entry(void)
85 {
86         uint32_t vcoreid = vcore_id();
87
88 /* begin: stuff userspace needs to do to handle notifications */
89         struct vcore *vc = &__procinfo.vcoremap[vcoreid];
90         struct preempt_data *vcpd;
91         vcpd = &__procdata.vcore_preempt_data[vcoreid];
92         
93         /* Lets try to restart vcore0's context.  Note this doesn't do anything to
94          * set the appropriate TLS.  On x86, this will involve changing the LDT
95          * entry for this vcore to point to the TCB of the new user-thread. */
96         if (vcoreid == 0) {
97                 handle_events(vcoreid);
98                 set_tls_desc(core0_tls, 0);
99                 assert(__vcoreid == 0); /* in case anyone uses this */
100                 /* Load silly state (Floating point) too */
101                 pop_user_ctx(&vcpd->uthread_ctx, vcoreid);
102                 panic("should never see me!");
103         }       
104 /* end: stuff userspace needs to do to handle notifications */
105
106         /* all other vcores are down here */
107         mcs_barrier_wait(&b, vcoreid);
108
109         udelay(1000000);
110         if (vcoreid == 1)
111                 printf("Proc %d's vcores are yielding\n", getpid());
112         sys_yield(0);
113
114         while(1);
115 }
116