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