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