Merge branch 'master' of ssh://waterman@scm.millennium.berkeley.edu/project/cs/radlab...
[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 <resource.h>
26 #include <monitor.h>
27 #include <colored_caches.h>
28 #include <string.h>
29
30 /*
31  * Currently, if you leave this function by way of proc_run (process_workqueue
32  * that proc_runs), you will never come back to where you left off, and the
33  * function will start from the top.  Hence the hack 'progress'.
34  */
35 void manager(void)
36 {
37         #ifndef DEVELOPER_NAME
38                 #define DEVELOPER_NAME brho
39         #endif
40
41         // LoL
42         #define PASTE(s1,s2) s1 ## s2
43         #define MANAGER_FUNC(dev) PASTE(manager_,dev)
44
45         void MANAGER_FUNC(DEVELOPER_NAME)(void);
46         MANAGER_FUNC(DEVELOPER_NAME)();
47 }
48
49 void manager_brho(void)
50 {
51         static uint8_t RACY progress = 0;
52
53         static struct proc *envs[256];
54         static struct proc *p ;
55
56         // for testing taking cores, check in case 1 for usage
57         uint32_t corelist[MAX_NUM_CPUS];
58         uint32_t num = 3;
59
60         switch (progress++) {
61                 case 0:
62                         // TODO: need to store the pid for future manager runs, not the *p
63                         p = kfs_proc_create(kfs_lookup_path("parlib_mhello"));
64                         //p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
65                         //p = kfs_proc_create(kfs_lookup_path("roslib_mproctests"));
66                         //p = kfs_proc_create(kfs_lookup_path("roslib_spawn"));
67                         // being proper and all:
68                         spin_lock_irqsave(&p->proc_lock);
69                         __proc_set_state(p, PROC_RUNNABLE_S);
70                         // normal single-cored way
71                         spin_unlock_irqsave(&p->proc_lock);
72                         proc_run(p);
73                         proc_decref(p, 1);
74                         #if 0
75                         // this is how you can transition to a parallel process manually
76                         // make sure you don't proc run first
77                         __proc_set_state(p, PROC_RUNNING_S);
78                         __proc_set_state(p, PROC_RUNNABLE_M);
79                         p->resources[RES_CORES].amt_wanted = 5;
80                         spin_unlock_irqsave(&p->proc_lock);
81                         core_request(p);
82                         panic("This is okay");
83                         #endif
84                         break;
85                 case 1:
86                         monitor(0);
87                         #if 0
88                         udelay(10000000);
89                         // this is a ghetto way to test restarting an _M
90                                 printk("\nattempting to ghetto preempt...\n");
91                                 spin_lock_irqsave(&p->proc_lock);
92                                 proc_take_allcores(p, __death);
93                                 __proc_set_state(p, PROC_RUNNABLE_M);
94                                 spin_unlock_irqsave(&p->proc_lock);
95                                 udelay(5000000);
96                                 printk("\nattempting to restart...\n");
97                                 core_request(p); // proc still wants the cores
98                         panic("This is okay");
99                         // this tests taking some cores, and later killing an _M
100                                 printk("taking 3 cores from p\n");
101                                 for (int i = 0; i < num; i++)
102                                         corelist[i] = 7-i; // 7, 6, and 5
103                                 spin_lock_irqsave(&p->proc_lock);
104                                 proc_take_cores(p, corelist, &num, __death);
105                                 spin_unlock_irqsave(&p->proc_lock);
106                                 udelay(5000000);
107                                 printk("Killing p\n");
108                                 proc_destroy(p);
109                                 printk("Killed p\n");
110                         panic("This is okay");
111
112                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
113                         __proc_set_state(envs[0], PROC_RUNNABLE_S);
114                         proc_run(envs[0]);
115                         break;
116                         #endif
117                 case 2:
118                         #if 0
119                         panic("Do not panic");
120                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
121                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
122                         smp_call_function_single(1, run_env_handler, envs[0], 0);
123                         smp_call_function_single(2, run_env_handler, envs[1], 0);
124                         break;
125                         #endif
126                 case 3:
127                 #if 0
128                 case 4:
129                         printk("Beginning Tests\n");
130                         test_run_measurements(progress-1);  // should never return
131                         break;
132                 case 5:
133                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
134                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
135                         smp_call_function_single(1, run_env_handler, envs[0], 0);
136                         smp_call_function_single(2, run_env_handler, envs[1], 0);
137                 case 6:
138                 #endif
139                 case 4:
140                         /*
141                         test_smp_call_functions();
142                         test_checklists();
143                         test_barrier();
144                         test_print_info();
145                         test_lapic_status_bit();
146                         test_ipi_sending();
147                         test_pit();
148                         */
149                 case 5:
150                 case 6:
151                 case 7:
152                 case 8:
153                 case 9:
154                 case 10:
155                 case 11:
156                 case 12:
157                 case 13:
158                 case 14:
159                         //test_run_measurements(progress-1);
160                 default:
161                         printk("Manager Progress: %d\n", progress);
162                         // delay if you want to test rescheduling an MCP that yielded
163                         //udelay(15000000);
164                         schedule();
165         }
166         panic("If you see me, then you probably screwed up");
167
168         /*
169         printk("Servicing syscalls from Core 0:\n\n");
170         while (1) {
171                 process_generic_syscalls(&envs[0], 1);
172                 cpu_relax();
173         }
174         */
175         return;
176 }
177
178 void manager_klueska()
179 {
180         static struct proc *envs[256];
181         static volatile uint8_t progress = 0;
182
183         if (progress == 0) {
184                 progress++;
185                 envs[0] = kfs_proc_create(kfs_lookup_path("parlib_matrix"));
186                 __proc_set_state(envs[0], PROC_RUNNABLE_S);
187                 proc_run(envs[0]);
188         }
189         schedule();
190
191         panic("DON'T PANIC");
192 }
193
194 void manager_waterman()
195 {
196         manager_klueska();
197 }
198
199 void manager_pearce()
200 {
201         manager_klueska();
202 }
203
204
205 #ifdef __sparc_v8__
206
207 static char*
208 itoa(int num, char* buf0, size_t base)
209 {
210         if(base > 16)
211                 return NULL;
212
213         char* buf = buf0;
214         int len = 0, i;
215
216         if(num < 0)
217         {
218                 *buf++ = '-';
219                 num = -num;
220         }
221
222         do {
223                 buf[len++] = "0123456789abcdef"[num%base];
224                 num /= base;
225         } while(num);
226
227         for(i = 0; i < len/2; i++)
228         {
229                 char temp = buf[i];
230                 buf[i] = buf[len-i-1];
231                 buf[len-i-1] = temp;
232         }
233         buf[len] = 0;
234
235         return buf0;
236 }
237
238 void gsf_set_frame_cycles(int cycles)
239 {
240         store_alternate(26*4,2,cycles);
241 }
242
243 void gsf_set_partition_credits(int partition, int credits)
244 {
245         store_alternate((32+partition)*4,2,credits);
246 }
247
248 void gsf_set_core_partition(int core, int partition)
249 {
250         store_alternate((64+core)*4,2,partition);
251 }
252
253 #endif
254