33e5d73d722032c654ed96ee80e086bc863045c7
[akaros.git] / user / apps / roslib / mhello.c
1 #include <lib.h>
2 #include <ros/mman.h>
3 #include <ros/resource.h>
4 #include <syswrapper.h>
5 #include <stdio.h>
6
7 // ghetto udelay, put in a lib somewhere and export the tsc freq
8 #include <arch/arch.h>
9 void udelay(uint64_t usec, uint64_t tsc_freq)
10 {
11         uint64_t start, end, now;
12
13         start = read_tsc();
14     end = start + (tsc_freq * usec) / 1000000;
15         if (end == 0) cprintf("This is terribly wrong \n");
16         do {
17         cpu_relax();
18         now = read_tsc();
19         } while (now < end || (now > start && end < start));
20         return;
21 }
22
23 #define TEST_MMAP                                       1
24 #define TEST_ONE_CORE                           2
25 #define TEST_ASK_FOR_TOO_MANY_CORES     3
26 #define TEST_INCREMENTAL_CHANGES        4
27 #define TEST_YIELD_OUT_OF_ORDER         5
28 #define TEST_YIELD_0_OUT_OF_ORDER       6
29 #define TEST_SWITCH_TO_RUNNABLE_S       7
30 #define TEST_CRAZY_YIELDS                       8
31 #define TEST_CONCURRENT_SYSCALLS        9
32
33 int main(int argc, char** argv)
34 {
35         uint32_t vcoreid;
36         error_t retval;
37
38         int test = TEST_INCREMENTAL_CHANGES;
39
40         static int first_time = 1; // used by vcore2
41
42         if ((vcoreid = newcore())) {
43                 cprintf("Hello from vcore %d\n", vcoreid);
44         } else { // core 0
45                 cprintf("Hello from else vcore 0\n");
46                 cprintf("Multi-Goodbye, world, from PID: %d!\n", sys_getpid());
47                 switch (test) {
48                         case TEST_MMAP:
49                                 cprintf("Testing MMAP\n");
50                                 void* addr;
51                                 addr = sys_mmap((void*SNT)USTACKTOP - 20*PGSIZE, 8*PGSIZE, 3,
52                                                 MAP_FIXED, 0, 0);
53                                 cprintf("got addr = 0x%08x\n", addr);
54                                 *(int*)addr = 0xdeadbeef;
55                                 *(int*)(addr + 3*PGSIZE) = 0xcafebabe;
56                                 // these should work
57                                 cprintf("reading addr: 0x%08x\n", *(int*)addr);
58                                 cprintf("reading addr+3pg: 0x%08x\n", *(int*)(addr + 3*PGSIZE));
59                                 // this should fault
60                                 cprintf("Should page fault and die now.\n");
61                                 *(int*)(addr - 3*PGSIZE) = 0xdeadbeef;
62                                 cprintf("Should not see me!!!!!!!!!!!!!!!!!!\n");
63                                 while(1);
64                         case TEST_ONE_CORE:
65                                 retval = sys_resource_req(RES_CORES, 1, 0);
66                                 cprintf("One core test's core0's retval: %d\n", retval);
67                                 cprintf("Check to see it's on a worker core.\n");
68                                 while(1);
69                         case TEST_ASK_FOR_TOO_MANY_CORES:
70                                 retval = sys_resource_req(RES_CORES, 12, 0);
71                                 cprintf("Asked for too many, retval: %d\n", retval);
72                                 return 0;
73                         case TEST_INCREMENTAL_CHANGES:
74                                 retval = sys_resource_req(RES_CORES, 4, 0);
75                                 break;
76                         default:
77                                 retval = sys_resource_req(RES_CORES, 7, 0);
78                 }
79                 cprintf("Should see me if you want to relocate core0's context "
80                         "when moving from RUNNING_S\n");
81         }
82         if ((vcoreid == 2) && first_time) {
83                 first_time = 0;
84                 switch (test) {
85                         case TEST_INCREMENTAL_CHANGES:
86                                 // Testing asking for less than we already have
87                                 udelay(1000000, 1995014570); // KVM's freq.  Whatever.
88                                 cprintf("Asking for too few:\n");
89                                 retval = sys_resource_req(RES_CORES, 2, 0);
90                                 cprintf("Should be -EINVAL(7): %d\n", retval);
91                                 // Testing getting more while running
92                                 cprintf("Asking for more while running:\n");
93                                 udelay(1000000, 1995014570);
94                                 retval = sys_resource_req(RES_CORES, 7, 0);
95                                 cprintf("core2's retval: %d\n", retval);
96                                 break;
97                         case TEST_YIELD_OUT_OF_ORDER:
98                                 cprintf("Core %d yielding\n", vcoreid);
99                                 yield();
100                                 break;
101                         case TEST_YIELD_0_OUT_OF_ORDER:
102                                 udelay(5000000, 1995014570);
103                                 cprintf("Core 0 should have yielded, asking for another\n");
104                                 retval = sys_resource_req(RES_CORES, 7, 0);
105                 }
106         }
107         if (vcoreid == 0) {
108                 switch (test) {
109                         case TEST_YIELD_OUT_OF_ORDER:
110                                 udelay(10000000, 1995014570);
111                                 cprintf("Core 2 should have yielded, asking for another\n");
112                                 retval = sys_resource_req(RES_CORES, 7, 0);
113                                 break;
114                         case TEST_YIELD_0_OUT_OF_ORDER:
115                                 udelay(5000000, 1995014570);
116                                 cprintf("Core %d yielding\n", vcoreid);
117                                 yield();
118                                 cprintf("Core 0 came back where it left off in RUNNING_M!!!\n");
119                                 break;
120                 }
121         }
122         /* This assumes the "core0 is the one who gets saved" style */
123         switch (test) {
124                 case TEST_SWITCH_TO_RUNNABLE_S:
125                         if (vcoreid) {
126                                 yield();
127                         } else {
128                                 udelay(5000000, 1995014570);
129                                 cprintf("Core %d yielding\n", vcoreid);
130                                 yield();
131                                 cprintf("Should see me if you are ever scheduled again.\n");
132                         }
133                         while(1);
134                 case TEST_CRAZY_YIELDS:
135                         udelay(300000*vcoreid, 1995014570);
136                         sys_resource_req(RES_CORES, 7, 0);
137                         yield();
138                         cprintf("should  never see me, unless you slip into *_S\n");
139                         break;
140                 case TEST_CONCURRENT_SYSCALLS:
141                         for (int i = 0; i < 10; i++) {
142                                 for (int j = 0; j < 100; j++)
143                                         sys_null();
144                                 cprintf("Hello from vcore %d, iteration %d\n", vcoreid, i);
145                         }
146                         break;
147         }
148         cprintf("Vcore %d Done!\n", vcoreid);
149         while (1);
150         return 0;
151 }