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