Uses kref in the FS, fixes up refcount bugs
[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 #include <ros/timer.h>
35 #include <ros/arch/membar.h>
36
37 /*
38  * Currently, if you leave this function by way of proc_run (process_workqueue
39  * that proc_runs), you will never come back to where you left off, and the
40  * function will start from the top.  Hence the hack 'progress'.
41  */
42 void manager(void)
43 {
44         #ifndef DEVELOPER_NAME
45                 #define DEVELOPER_NAME brho
46         #endif
47
48         // LoL
49         #define PASTE(s1,s2) s1 ## s2
50         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
51
52         void MANAGER_FUNC(DEVELOPER_NAME)(void);
53         MANAGER_FUNC(DEVELOPER_NAME)();
54 }
55
56 char *p_argv[] = {0, 0, 0};
57 char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
58 /* Helper macro for quickly running a process.  Pass it a string, *file, and a
59  * *proc. */
60 #define quick_proc_run(x, p, f)                                                  \
61         (f) = path_to_file((x));                                                     \
62         assert((f));                                                                 \
63         p_argv[0] = file_name((f));                                               \
64         (p) = proc_create((f), p_argv, p_envp);                                      \
65         kref_put(&(f)->f_kref);                                                      \
66         spin_lock(&(p)->proc_lock);                                                  \
67         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
68         spin_unlock(&(p)->proc_lock);                                                \
69         proc_run((p));                                                               \
70         kref_put(&(p)->kref);
71
72 #define quick_proc_create(x, p, f)                                               \
73         (f) = path_to_file((x));                                                     \
74         assert((f));                                                                 \
75         p_argv[0] = file_name((f));                                               \
76         (p) = proc_create((f), p_argv, p_envp);                                      \
77         kref_put(&(f)->f_kref);                                                      \
78         spin_lock(&(p)->proc_lock);                                                  \
79         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
80         spin_unlock(&(p)->proc_lock);
81
82 #define quick_proc_color_run(x, p, c, f)                                         \
83         (f) = path_to_file((x));                                                     \
84         assert((f));                                                                 \
85         p_argv[0] = file_name((f));                                               \
86         (p) = proc_create((f), p_argv, p_envp);                                      \
87         kref_put(&(f)->f_kref);                                                      \
88         spin_lock(&(p)->proc_lock);                                                  \
89         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
90         spin_unlock(&(p)->proc_lock);                                                \
91         p->cache_colors_map = cache_colors_map_alloc();                              \
92         for (int i = 0; i < (c); i++)                                                \
93                 cache_color_alloc(llc_cache, p->cache_colors_map);                       \
94         proc_run((p));                                                               \
95         kref_put(&(p)->kref);
96
97 #define quick_proc_color_create(x, p, c, f)                                      \
98         (f) = path_to_file((x));                                                     \
99         assert((f));                                                                 \
100         p_argv[0] = file_name((f));                                               \
101         (p) = proc_create((f), p_argv, p_envp);                                      \
102         kref_put(&(f)->f_kref);                                                      \
103         spin_lock(&(p)->proc_lock);                                                  \
104         __proc_set_state((p), PROC_RUNNABLE_S);                                      \
105         spin_unlock(&(p)->proc_lock);                                                \
106         p->cache_colors_map = cache_colors_map_alloc();                              \
107         for (int i = 0; i < (c); i++)                                                \
108                 cache_color_alloc(llc_cache, p->cache_colors_map);
109
110 void manager_brho(void)
111 {
112         static uint8_t RACY progress = 0;
113         static struct proc *p;
114         struct file *temp_f;
115
116         // for testing taking cores, check in case 1 for usage
117         uint32_t corelist[MAX_NUM_CPUS];
118         uint32_t num = 3;
119
120         switch (progress++) {
121                 case 0:
122                         /* 124 is half of the available boxboro colors (with the kernel
123                          * getting 8) */
124                         //quick_proc_color_run("msr_dumb_while", p, 124, temp_f);
125                         quick_proc_run("/bin/hello", p, temp_f);
126                         #if 0
127                         // this is how you can transition to a parallel process manually
128                         // make sure you don't proc run first
129                         __proc_set_state(p, PROC_RUNNING_S);
130                         __proc_set_state(p, PROC_RUNNABLE_M);
131                         p->resources[RES_CORES].amt_wanted = 5;
132                         spin_unlock(&p->proc_lock);
133                         core_request(p);
134                         panic("This is okay");
135                         #endif
136                         break;
137                 case 1:
138                         #if 0
139                         udelay(10000000);
140                         // this is a ghetto way to test restarting an _M
141                                 printk("\nattempting to ghetto preempt...\n");
142                                 spin_lock(&p->proc_lock);
143                                 proc_take_allcores(p, __death);
144                                 __proc_set_state(p, PROC_RUNNABLE_M);
145                                 spin_unlock(&p->proc_lock);
146                                 udelay(5000000);
147                                 printk("\nattempting to restart...\n");
148                                 core_request(p); // proc still wants the cores
149                         panic("This is okay");
150                         // this tests taking some cores, and later killing an _M
151                                 printk("taking 3 cores from p\n");
152                                 for (int i = 0; i < num; i++)
153                                         corelist[i] = 7-i; // 7, 6, and 5
154                                 spin_lock(&p->proc_lock);
155                                 proc_take_cores(p, corelist, &num, __death);
156                                 spin_unlock(&p->proc_lock);
157                                 udelay(5000000);
158                                 printk("Killing p\n");
159                                 proc_destroy(p);
160                                 printk("Killed p\n");
161                         panic("This is okay");
162
163                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
164                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
165                         proc_run(envs[0]);
166                         break;
167                         #endif
168                 case 2:
169                         /*
170                         test_smp_call_functions();
171                         test_checklists();
172                         test_barrier();
173                         test_print_info();
174                         test_lapic_status_bit();
175                         test_ipi_sending();
176                         test_pit();
177                         */
178                 default:
179                         printd("Manager Progress: %d\n", progress);
180                         // delay if you want to test rescheduling an MCP that yielded
181                         //udelay(15000000);
182                         schedule();
183         }
184         panic("If you see me, then you probably screwed up");
185         monitor(0);
186
187         /*
188         printk("Servicing syscalls from Core 0:\n\n");
189         while (1) {
190                 process_generic_syscalls(&envs[0], 1);
191                 cpu_relax();
192         }
193         */
194         return;
195 }
196
197 void manager_klueska()
198 {
199         static struct proc *envs[256];
200         static volatile uint8_t progress = 0;
201
202         if (progress == 0) {
203                 progress++;
204                 panic("what do you want to do?");
205                 //envs[0] = kfs_proc_create(kfs_lookup_path("fillmeup"));
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 struct elf_info
215 {
216         long entry;
217         long phdr;
218         int phnum;
219         int dynamic;
220         char interp[256];
221 };
222
223 void manager_waterman()
224 {
225         static int init = 0;
226         if(!init)
227         {
228                 warn("Old file creation might not work");
229                 init = 1;
230                 struct proc *p;
231                 proc_alloc(&p, 0);
232
233                 char* argv[] = {"/bin/sh","-l",0};
234                 char* envp[] = {"LD_LIBRARY_PATH=/lib",0};
235                 procinfo_pack_args(p->procinfo,argv,envp);
236
237                 struct file* f = file_open("/bin/busybox",0,0);
238                 assert(f != NULL);
239                 assert(load_elf(p,f) == 0);
240                 file_decref(f);
241
242                 __proc_set_state(p, PROC_RUNNABLE_S);
243                 proc_run(p);
244         }
245         schedule();
246 }
247
248 void manager_pearce()
249 {
250         static struct proc *envs[256];
251         static volatile uint8_t progress = 0;
252
253         if (progress == 0) {
254                 progress++;
255                 panic("what do you want to do?");
256                 //envs[0] = kfs_proc_create(kfs_lookup_path("parlib_httpserver_integrated"));
257                 //envs[0] = kfs_proc_create(kfs_lookup_path("parlib_lock_test"));
258                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
259                 proc_run(envs[0]);
260         }
261         schedule();
262
263         panic("DON'T PANIC");
264
265 }
266
267 #ifdef __sparc_v8__
268
269 static char*
270 itoa(int num, char* buf0, size_t base)
271 {
272         if(base > 16)
273                 return NULL;
274
275         char* buf = buf0;
276         int len = 0, i;
277
278         if(num < 0)
279         {
280                 *buf++ = '-';
281                 num = -num;
282         }
283
284         do {
285                 buf[len++] = "0123456789abcdef"[num%base];
286                 num /= base;
287         } while(num);
288
289         for(i = 0; i < len/2; i++)
290         {
291                 char temp = buf[i];
292                 buf[i] = buf[len-i-1];
293                 buf[len-i-1] = temp;
294         }
295         buf[len] = 0;
296
297         return buf0;
298 }
299
300 void gsf_set_frame_cycles(int cycles)
301 {
302         store_alternate(26*4,2,cycles);
303 }
304
305 void gsf_set_partition_credits(int partition, int credits)
306 {
307         store_alternate((32+partition)*4,2,credits);
308 }
309
310 void gsf_set_core_partition(int core, int partition)
311 {
312         store_alternate((64+core)*4,2,partition);
313 }
314
315 #endif
316