Preemption functions
[akaros.git] / kern / src / manager.c
1 /*
2  * Copyright (c) 2009 The Regents of the University of California
3  * Barret Rhoden <brho@cs.berkeley.edu>
4  * See LICENSE for details.
5  */
6
7
8 #ifdef __SHARC__
9 #pragma nosharc
10 #endif
11
12 #include <ros/common.h>
13 #include <smp.h>
14 #include <arch/init.h>
15 #include <mm.h>
16 #include <elf.h>
17 #include <frontend.h>
18
19 #include <kmalloc.h>
20 #include <assert.h>
21 #include <manager.h>
22 #include <process.h>
23 #include <schedule.h>
24 #include <syscall.h>
25 #include <testing.h>
26 #include <kfs.h>
27 #include <stdio.h>
28 #include <timing.h>
29 #include <resource.h>
30 #include <monitor.h>
31 #include <colored_caches.h>
32 #include <string.h>
33 #include <pmap.h>
34
35 /*
36  * Currently, if you leave this function by way of proc_run (process_workqueue
37  * that proc_runs), you will never come back to where you left off, and the
38  * function will start from the top.  Hence the hack 'progress'.
39  */
40 void manager(void)
41 {
42         #ifndef DEVELOPER_NAME
43                 #define DEVELOPER_NAME brho
44         #endif
45
46         // LoL
47         #define PASTE(s1,s2) s1 ## s2
48         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
49
50         void MANAGER_FUNC(DEVELOPER_NAME)(void);
51         MANAGER_FUNC(DEVELOPER_NAME)();
52 }
53
54 void manager_brho(void)
55 {
56         static uint8_t RACY progress = 0;
57
58         static struct proc *envs[256];
59         static struct proc *p ;
60
61         // for testing taking cores, check in case 1 for usage
62         uint32_t corelist[MAX_NUM_CPUS];
63         uint32_t num = 3;
64
65         switch (progress++) {
66                 case 0:
67                         // TODO: need to store the pid for future manager runs, not the *p
68                         //p = kfs_proc_create(kfs_lookup_path("pthread_test"));
69                         //p = kfs_proc_create(kfs_lookup_path("mhello"));
70                         p = kfs_proc_create(kfs_lookup_path("msr_dumb_while"));
71                         // being proper and all:
72                         spin_lock(&p->proc_lock);
73                         __proc_set_state(p, PROC_RUNNABLE_S);
74                         // normal single-cored way
75                         spin_unlock(&p->proc_lock);
76                         proc_run(p);
77                         proc_decref(p, 1);
78                         #if 0
79                         // this is how you can transition to a parallel process manually
80                         // make sure you don't proc run first
81                         __proc_set_state(p, PROC_RUNNING_S);
82                         __proc_set_state(p, PROC_RUNNABLE_M);
83                         p->resources[RES_CORES].amt_wanted = 5;
84                         spin_unlock(&p->proc_lock);
85                         core_request(p);
86                         panic("This is okay");
87                         #endif
88                         break;
89                 case 1:
90                         //monitor(0);
91                         #if 0
92                         udelay(10000000);
93                         // this is a ghetto way to test restarting an _M
94                                 printk("\nattempting to ghetto preempt...\n");
95                                 spin_lock(&p->proc_lock);
96                                 proc_take_allcores(p, __death);
97                                 __proc_set_state(p, PROC_RUNNABLE_M);
98                                 spin_unlock(&p->proc_lock);
99                                 udelay(5000000);
100                                 printk("\nattempting to restart...\n");
101                                 core_request(p); // proc still wants the cores
102                         panic("This is okay");
103                         // this tests taking some cores, and later killing an _M
104                                 printk("taking 3 cores from p\n");
105                                 for (int i = 0; i < num; i++)
106                                         corelist[i] = 7-i; // 7, 6, and 5
107                                 spin_lock(&p->proc_lock);
108                                 proc_take_cores(p, corelist, &num, __death);
109                                 spin_unlock(&p->proc_lock);
110                                 udelay(5000000);
111                                 printk("Killing p\n");
112                                 proc_destroy(p);
113                                 printk("Killed p\n");
114                         panic("This is okay");
115
116                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
117                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
118                         proc_run(envs[0]);
119                         break;
120                         #endif
121                 case 2:
122                         /*
123                         test_smp_call_functions();
124                         test_checklists();
125                         test_barrier();
126                         test_print_info();
127                         test_lapic_status_bit();
128                         test_ipi_sending();
129                         test_pit();
130                         */
131                 default:
132                         printd("Manager Progress: %d\n", progress);
133                         // delay if you want to test rescheduling an MCP that yielded
134                         //udelay(15000000);
135                         schedule();
136         }
137         panic("If you see me, then you probably screwed up");
138
139         /*
140         printk("Servicing syscalls from Core 0:\n\n");
141         while (1) {
142                 process_generic_syscalls(&envs[0], 1);
143                 cpu_relax();
144         }
145         */
146         return;
147 }
148
149 void manager_klueska()
150 {
151         static struct proc *envs[256];
152         static volatile uint8_t progress = 0;
153
154         if (progress == 0) {
155                 progress++;
156                 envs[0] = kfs_proc_create(kfs_lookup_path("fillmeup"));
157                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
158                 proc_run(envs[0]);
159         }
160         schedule();
161
162         panic("DON'T PANIC");
163 }
164
165 struct elf_info
166 {
167         long entry;
168         long phdr;
169         int phnum;
170         int dynamic;
171         char interp[256];
172 };
173
174 void manager_waterman()
175 {
176         static int init = 0;
177         if(!init)
178         {
179                 init = 1;
180                 struct proc* p = proc_create(NULL,0);
181
182                 char* argv[] = {"/bin/sh","-l",0};
183                 char* envp[] = {"LD_LIBRARY_PATH=/lib",0};
184                 procinfo_pack_args(p->procinfo,argv,envp);
185
186                 struct file* f = file_open("/bin/busybox",0,0);
187                 assert(f != NULL);
188                 assert(load_elf(p,f) == 0);
189                 file_decref(f);
190
191                 __proc_set_state(p, PROC_RUNNABLE_S);
192                 proc_run(p);
193         }
194         schedule();
195 }
196
197 void manager_pearce()
198 {
199         static struct proc *envs[256];
200         static volatile uint8_t progress = 0;
201
202         if (progress == 0) {
203                 progress++;
204                 envs[0] = kfs_proc_create(kfs_lookup_path("parlib_httpserver_integrated"));
205                 //envs[0] = kfs_proc_create(kfs_lookup_path("parlib_lock_test"));
206                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
207                 proc_run(envs[0]);
208         }
209         schedule();
210
211         panic("DON'T PANIC");
212
213 }
214
215
216 #ifdef __sparc_v8__
217
218 static char*
219 itoa(int num, char* buf0, size_t base)
220 {
221         if(base > 16)
222                 return NULL;
223
224         char* buf = buf0;
225         int len = 0, i;
226
227         if(num < 0)
228         {
229                 *buf++ = '-';
230                 num = -num;
231         }
232
233         do {
234                 buf[len++] = "0123456789abcdef"[num%base];
235                 num /= base;
236         } while(num);
237
238         for(i = 0; i < len/2; i++)
239         {
240                 char temp = buf[i];
241                 buf[i] = buf[len-i-1];
242                 buf[len-i-1] = temp;
243         }
244         buf[len] = 0;
245
246         return buf0;
247 }
248
249 void gsf_set_frame_cycles(int cycles)
250 {
251         store_alternate(26*4,2,cycles);
252 }
253
254 void gsf_set_partition_credits(int partition, int credits)
255 {
256         store_alternate((32+partition)*4,2,credits);
257 }
258
259 void gsf_set_core_partition(int core, int partition)
260 {
261         store_alternate((64+core)*4,2,partition);
262 }
263
264 #endif
265