sped up run binary... realloc sux
[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 #ifdef __SHARC__
8 #pragma nosharc
9 #endif
10
11 #include <ros/common.h>
12 #include <smp.h>
13 #include <arch/init.h>
14
15 #include <assert.h>
16 #include <manager.h>
17 #include <process.h>
18 #include <schedule.h>
19 #include <workqueue.h>
20 #include <syscall.h>
21 #include <testing.h>
22 #include <kfs.h>
23 #include <stdio.h>
24 #include <timing.h>
25 #include <colored_caches.h>
26 #include <string.h>
27
28 /*
29  * Currently, if you leave this function by way of proc_run (process_workqueue
30  * that proc_runs), you will never come back to where you left off, and the
31  * function will start from the top.  Hence the hack 'progress'.
32  */
33 void manager(void)
34 {
35         #ifndef DEVELOPER_NAME
36                 #define DEVELOPER_NAME brho
37         #endif
38
39         // LoL
40         #define PASTE(s1,s2) s1 ## s2
41         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
42
43         void MANAGER_FUNC(DEVELOPER_NAME)(void);
44         MANAGER_FUNC(DEVELOPER_NAME)();
45 }
46
47 void manager_brho(void)
48 {
49         static uint8_t RACY progress = 0;
50
51         static struct proc *envs[256];
52         static struct proc *p ;
53
54         uint32_t corelist[MAX_NUM_CPUS];
55         uint32_t num = 3;
56
57         switch (progress++) {
58                 case 0:
59                         //p = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
60                         p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
61                         // being proper and all:
62                         spin_lock_irqsave(&p->proc_lock);
63                         proc_set_state(p, PROC_RUNNABLE_S);
64                         // normal single-cored way
65                         spin_unlock_irqsave(&p->proc_lock);
66                         proc_run(p);
67                         #if 0
68                         // this is how you can transition to a parallel process manually
69                         // make sure you don't proc run first
70                         proc_set_state(p, PROC_RUNNING_S);
71                         proc_set_state(p, PROC_RUNNABLE_M);
72                         p->resources[RES_CORES].amt_wanted = 5;
73                         spin_unlock_irqsave(&p->proc_lock);
74                         core_request(p);
75                         panic("This is okay");
76                         #endif
77                         break;
78                 case 1:
79                         #if 0
80                         panic("This is okay");
81                         udelay(10000000);
82                         printk("taking 3 cores from p\n");
83                         for (int i = 0; i < num; i++)
84                                 corelist[i] = 7-i; // 7, 6, and 5
85                         spin_lock_irqsave(&p->proc_lock);
86                         proc_take_cores(p, corelist, &num, __death);
87                         spin_unlock_irqsave(&p->proc_lock);
88                         udelay(5000000);
89                         printk("Killing p\n");
90                         proc_destroy(p);
91                         printk("Killed p\n");
92                         udelay(1000000);
93                         panic("This is okay");
94
95                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
96                         proc_set_state(envs[0], PROC_RUNNABLE_S);
97                         proc_run(envs[0]);
98                         break;
99                         #endif
100         #ifdef __i386__
101                 case 2:
102                         #if 0
103                         panic("Do not panic");
104                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
105                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
106                         smp_call_function_single(1, run_env_handler, envs[0], 0);
107                         smp_call_function_single(2, run_env_handler, envs[1], 0);
108                         break;
109                         #endif
110                 case 3:
111         #else // sparc
112                 case 2:
113                         panic("Do not panic");
114                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
115                         envs[1] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
116                         envs[2] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
117                         envs[3] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
118                         envs[4] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
119                         envs[4] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
120                         envs[5] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
121                         envs[6] = kfs_proc_create(kfs_lookup_path("roslib_null"));
122                         proc_run(envs[0]);
123                         break;
124                 case 3:
125                         #if 0
126                         // reminder of how to spawn remotely
127                         for (int i = 0; i < 8; i++) {
128                                 envs[i] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
129                                 proc_set_state(envs[i], PROC_RUNNABLE_S);
130                                 smp_call_function_single(i, run_env_handler, envs[i], 0);
131                         }
132                         process_workqueue();
133                         #endif
134         #endif
135
136                 #if 0
137                 case 4:
138                         printk("Beginning Tests\n");
139                         test_run_measurements(progress-1);  // should never return
140                         break;
141                 case 5:
142                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
143                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
144                         smp_call_function_single(1, run_env_handler, envs[0], 0);
145                         smp_call_function_single(2, run_env_handler, envs[1], 0);
146                 case 6:
147                 #endif
148                 case 4:
149                         /*
150                         test_smp_call_functions();
151                         test_checklists();
152                         test_barrier();
153                         test_print_info();
154                         test_lapic_status_bit();
155                         test_ipi_sending();
156                         test_pit();
157                         */
158                 case 5:
159                 case 6:
160                 case 7:
161                 case 8:
162                 case 9:
163                 case 10:
164                 case 11:
165                 case 12:
166                 case 13:
167                 case 14:
168                         //test_run_measurements(progress-1);
169                 default:
170                         printk("Manager Progress: %d\n", progress);
171                         // delay if you want to test rescheduling an MCP that yielded
172                         //udelay(15000000);
173                         schedule();
174         }
175         panic("If you see me, then you probably screwed up");
176
177         /*
178         printk("Servicing syscalls from Core 0:\n\n");
179         while (1) {
180                 process_generic_syscalls(&envs[0], 1);
181                 cpu_relax();
182         }
183         */
184         return;
185 }
186
187 void manager_klueska()
188 {
189         static struct proc *envs[256];
190         static uint8_t progress = 0;
191
192         if (progress++ == 0) {
193                 envs[0] = kfs_proc_create(kfs_lookup_path("parlib_matrix"));
194                 proc_set_state(envs[0], PROC_RUNNABLE_S);
195                 proc_run(envs[0]);
196         }
197         schedule();
198
199         panic("DON'T PANIC");
200 }
201
202 #ifdef __sparc_v8__
203
204 static char*
205 itoa(int num, char* buf0, size_t base)
206 {
207         if(base > 16)
208                 return NULL;
209
210         char* buf = buf0;
211         int len = 0, i;
212
213         if(num < 0)
214         {
215                 *buf++ = '-';
216                 num = -num;
217         }
218
219         do {
220                 buf[len++] = "0123456789abcdef"[num%base];
221                 num /= base;
222         } while(num);
223
224         for(i = 0; i < len/2; i++)
225         {
226                 char temp = buf[i];
227                 buf[i] = buf[len-i-1];
228                 buf[len-i-1] = temp;
229         }
230         buf[len] = 0;
231
232         return buf0;
233 }
234
235 void gsf_set_frame_cycles(int cycles)
236 {
237         store_alternate(26*4,2,cycles);
238 }
239
240 void gsf_set_partition_credits(int partition, int credits)
241 {
242         store_alternate((32+partition)*4,2,credits);
243 }
244
245 void gsf_set_core_partition(int core, int partition)
246 {
247         store_alternate((64+core)*4,2,partition);
248 }
249
250 #endif
251
252 void manager_waterman()
253 {
254 #ifdef __sparc_v8__
255
256         static uint8_t progress = 0;
257         if(progress > 0)
258                 goto run_some_apps;     
259
260         #define MAX_APPS 2
261         struct app
262         {
263                 int threads;
264                 int colors;
265                 int credits;
266                 int argc;
267                 char** argv;
268         };
269
270         static struct app apps[MAX_APPS];
271         static int napps = 0;
272
273         // arg format:
274         // #apps [#threads #colors #credits name args] - [#threads ...] - ...
275         assert(argc > 0);
276         napps = atoi(argv[0]);
277         assert(napps <= MAX_APPS);
278         argc--; argv++;
279         for(int a = 0; a < napps; a++)
280         {
281                 assert(argc >= 4);
282                 apps[a].threads = atoi(argv[0]);
283                 apps[a].colors = atoi(argv[1]);
284                 apps[a].credits = atoi(argv[2]);
285                 argc -= 3; argv += 3;
286
287                 apps[a].argc = 0;
288                 apps[a].argv = argv;
289                 while(argc)
290                 {
291                         argc--;
292                         if(strcmp(*argv++,"-") != 0)
293                                 apps[a].argc++;
294                         else
295                                 break;
296                 }
297
298                 printk("app %d: %d threads, %d colors, %d credits\ncommand line: ",a,apps[a].threads,apps[a].colors,apps[a].credits);
299                 for(int i = 0; i < apps[a].argc; i++)
300                         printk("%s ",apps[a].argv[i]);
301                 printk("\n");
302         }
303
304         // DRAM can process requests every 40 cycles.
305         // In a 480-cycle window, this gives us 12 total credits.
306         gsf_set_frame_cycles(482);
307         for(int a = 0, cores_used = 0; a < napps; a++)
308         {
309                 gsf_set_partition_credits(a,apps[a].credits);
310                 for(int i = 0; i < apps[a].threads; i++, cores_used++)
311                         gsf_set_core_partition(num_cpus-cores_used-1,a);
312         }
313
314 run_some_apps:
315         ;
316
317         static struct proc *envs[MAX_APPS];
318         int apps_running = napps;
319         int envs_free[MAX_APPS] = {0};
320         if(progress == napps)
321         {
322                 while(apps_running)
323                 {
324                         for(int i = 0; i < napps; i++)
325                         {
326                                 if(*(volatile uint32_t*)&envs[i]->state == ENV_FREE && !envs_free[i])
327                                 {
328                                         envs_free[i] = 1;
329                                         apps_running--;
330                                         printk("Finished application %d at cycle %lld\n", i, read_tsc()); 
331                                 }
332                         }
333                 }
334                 reboot();
335         }
336         else
337         {
338                 envs[progress] = kfs_proc_create(kfs_lookup_path(apps[progress].argv[0]));
339
340                 envs[progress]->cache_colors_map = cache_colors_map_alloc();
341                 for(int i = 0; i < apps[progress].colors; i++)
342                         assert(cache_color_alloc(llc_cache, envs[progress]->cache_colors_map) == ESUCCESS);
343
344                 proc_set_state(envs[progress], PROC_RUNNABLE_S);
345
346                 if(apps[progress].argc)
347                         proc_init_argc_argv(envs[progress],apps[progress].argc,(const char**)apps[progress].argv);
348
349                 proc_run(envs[progress++]);
350
351                 schedule();
352         }
353 #endif
354         panic("professional bomb technician at work.  if you see me running, try to keep up!");
355 }