MCPs -> Many Filthy _S Ps
[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                         // being proper and all:
71                         spin_lock(&p->proc_lock);
72                         __proc_set_state(p, PROC_RUNNABLE_S);
73                         // normal single-cored way
74                         spin_unlock(&p->proc_lock);
75                         proc_run(p);
76                         proc_decref(p, 1);
77                         #if 0
78                         // this is how you can transition to a parallel process manually
79                         // make sure you don't proc run first
80                         __proc_set_state(p, PROC_RUNNING_S);
81                         __proc_set_state(p, PROC_RUNNABLE_M);
82                         p->resources[RES_CORES].amt_wanted = 5;
83                         spin_unlock(&p->proc_lock);
84                         core_request(p);
85                         panic("This is okay");
86                         #endif
87                         break;
88                 case 1:
89                         //monitor(0);
90                         #if 0
91                         udelay(10000000);
92                         // this is a ghetto way to test restarting an _M
93                                 printk("\nattempting to ghetto preempt...\n");
94                                 spin_lock(&p->proc_lock);
95                                 proc_take_allcores(p, __death);
96                                 __proc_set_state(p, PROC_RUNNABLE_M);
97                                 spin_unlock(&p->proc_lock);
98                                 udelay(5000000);
99                                 printk("\nattempting to restart...\n");
100                                 core_request(p); // proc still wants the cores
101                         panic("This is okay");
102                         // this tests taking some cores, and later killing an _M
103                                 printk("taking 3 cores from p\n");
104                                 for (int i = 0; i < num; i++)
105                                         corelist[i] = 7-i; // 7, 6, and 5
106                                 spin_lock(&p->proc_lock);
107                                 proc_take_cores(p, corelist, &num, __death);
108                                 spin_unlock(&p->proc_lock);
109                                 udelay(5000000);
110                                 printk("Killing p\n");
111                                 proc_destroy(p);
112                                 printk("Killed p\n");
113                         panic("This is okay");
114
115                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
116                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
117                         proc_run(envs[0]);
118                         break;
119                         #endif
120                 case 2:
121                         /*
122                         test_smp_call_functions();
123                         test_checklists();
124                         test_barrier();
125                         test_print_info();
126                         test_lapic_status_bit();
127                         test_ipi_sending();
128                         test_pit();
129                         */
130                 default:
131                         printd("Manager Progress: %d\n", progress);
132                         // delay if you want to test rescheduling an MCP that yielded
133                         //udelay(15000000);
134                         schedule();
135         }
136         panic("If you see me, then you probably screwed up");
137
138         /*
139         printk("Servicing syscalls from Core 0:\n\n");
140         while (1) {
141                 process_generic_syscalls(&envs[0], 1);
142                 cpu_relax();
143         }
144         */
145         return;
146 }
147
148 void manager_klueska()
149 {
150         static struct proc *envs[256];
151         static volatile uint8_t progress = 0;
152
153         if (progress == 0) {
154                 progress++;
155                 envs[0] = kfs_proc_create(kfs_lookup_path("fillmeup"));
156                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
157                 proc_run(envs[0]);
158         }
159         schedule();
160
161         panic("DON'T PANIC");
162 }
163
164 struct elf_info
165 {
166         long entry;
167         long phdr;
168         int phnum;
169         int dynamic;
170         char interp[256];
171 };
172
173 void manager_waterman()
174 {
175         static int init = 0;
176         if(!init)
177         {
178                 init = 1;
179                 struct proc* p = proc_create(NULL,0);
180
181                 char* argv[] = {"/bin/sh","-l",0};
182                 char* envp[] = {"LD_LIBRARY_PATH=/lib",0};
183                 procinfo_pack_args(p->procinfo,argv,envp);
184
185                 struct file* f = file_open("/bin/busybox",0,0);
186                 assert(f != NULL);
187                 assert(load_elf(p,f) == 0);
188                 file_decref(f);
189
190                 __proc_set_state(p, PROC_RUNNABLE_S);
191                 proc_run(p);
192         }
193         schedule();
194 }
195
196 void manager_pearce()
197 {
198         static struct proc *envs[256];
199         static volatile uint8_t progress = 0;
200
201         if (progress == 0) {
202                 progress++;
203                 envs[0] = kfs_proc_create(kfs_lookup_path("parlib_httpserver_integrated"));
204                 //envs[0] = kfs_proc_create(kfs_lookup_path("parlib_lock_test"));
205                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
206                 proc_run(envs[0]);
207         }
208         schedule();
209
210         panic("DON'T PANIC");
211
212 }
213
214
215 #ifdef __sparc_v8__
216
217 static char*
218 itoa(int num, char* buf0, size_t base)
219 {
220         if(base > 16)
221                 return NULL;
222
223         char* buf = buf0;
224         int len = 0, i;
225
226         if(num < 0)
227         {
228                 *buf++ = '-';
229                 num = -num;
230         }
231
232         do {
233                 buf[len++] = "0123456789abcdef"[num%base];
234                 num /= base;
235         } while(num);
236
237         for(i = 0; i < len/2; i++)
238         {
239                 char temp = buf[i];
240                 buf[i] = buf[len-i-1];
241                 buf[len-i-1] = temp;
242         }
243         buf[len] = 0;
244
245         return buf0;
246 }
247
248 void gsf_set_frame_cycles(int cycles)
249 {
250         store_alternate(26*4,2,cycles);
251 }
252
253 void gsf_set_partition_credits(int partition, int credits)
254 {
255         store_alternate((32+partition)*4,2,credits);
256 }
257
258 void gsf_set_core_partition(int core, int partition)
259 {
260         store_alternate((64+core)*4,2,partition);
261 }
262
263 #endif
264