Yield for single and parallel processes
[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
14 #include <assert.h>
15 #include <manager.h>
16 #include <process.h>
17 #include <schedule.h>
18 #include <workqueue.h>
19 #include <syscall.h>
20 #include <testing.h>
21 #include <kfs.h>
22 #include <stdio.h>
23 #include <timing.h>
24
25 /*
26  * Currently, if you leave this function by way of proc_run (process_workqueue
27  * that proc_runs), you will never come back to where you left off, and the
28  * function will start from the top.  Hence the hack 'progress'.
29  */
30 void manager(void)
31 {
32         static uint8_t RACY progress = 0;
33
34         struct proc *envs[256];
35         static struct proc *p ;
36
37         uint32_t corelist[MAX_NUM_CPUS];
38         uint32_t num = 3;
39
40         // This is a bypass of the standard manager structure, for network use
41         // If enabled, this spawns parlib_matrix, and allows the execution
42         // of a remote binary to function correctly (schedule() call below)
43         #ifdef __NETWORK__      
44         if (progress++ == 0) {
45                 envs[0] = kfs_proc_create(kfs_lookup_path("parlib_matrix"));
46                 proc_set_state(envs[0], PROC_RUNNABLE_S);
47                 proc_run(envs[0]);
48         }
49         schedule();
50         #endif 
51
52         switch (progress++) {
53                 case 0:
54                         //p = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
55                         p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
56                         // being proper and all:
57                         spin_lock_irqsave(&p->proc_lock);
58                         proc_set_state(p, PROC_RUNNABLE_S);
59                         // normal single-cored way
60                         spin_unlock_irqsave(&p->proc_lock);
61                         proc_run(p);
62                         #if 0
63                         // this is how you can transition to a parallel process manually
64                         // make sure you don't proc run first
65                         proc_set_state(p, PROC_RUNNING_S);
66                         proc_set_state(p, PROC_RUNNABLE_M);
67                         p->resources[RES_CORES].amt_wanted = 5;
68                         spin_unlock_irqsave(&p->proc_lock);
69                         core_request(p);
70                         panic("This is okay");
71                         #endif
72                         break;
73                 case 1:
74                         #if 0
75                         panic("This is okay");
76                         udelay(10000000);
77                         printk("taking 3 cores from p\n");
78                         for (int i = 0; i < num; i++)
79                                 corelist[i] = 7-i; // 7, 6, and 5
80                         spin_lock_irqsave(&p->proc_lock);
81                         proc_take_cores(p, corelist, &num, __death);
82                         spin_unlock_irqsave(&p->proc_lock);
83                         udelay(5000000);
84                         printk("Killing p\n");
85                         proc_destroy(p);
86                         printk("Killed p\n");
87                         udelay(1000000);
88                         panic("This is okay");
89
90                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
91                         proc_set_state(envs[0], PROC_RUNNABLE_S);
92                         proc_run(envs[0]);
93                         break;
94                         #endif
95         #ifdef __i386__
96                 case 2:
97                         #if 0
98                         panic("Do not panic");
99                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
100                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
101                         smp_call_function_single(1, run_env_handler, envs[0], 0);
102                         smp_call_function_single(2, run_env_handler, envs[1], 0);
103                         break;
104                         #endif
105                 case 3:
106         #else // sparc
107                 case 2:
108                         panic("Do not panic");
109                         envs[0] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
110                         envs[1] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
111                         envs[2] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
112                         envs[3] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
113                         envs[4] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
114                         envs[4] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
115                         envs[5] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
116                         envs[6] = kfs_proc_create(kfs_lookup_path("roslib_null"));
117                         proc_run(envs[0]);
118                         break;
119                 case 3:
120                         #if 0
121                         // reminder of how to spawn remotely
122                         for (int i = 0; i < 8; i++) {
123                                 envs[i] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
124                                 proc_set_state(envs[i], PROC_RUNNABLE_S);
125                                 smp_call_function_single(i, run_env_handler, envs[i], 0);
126                         }
127                         process_workqueue();
128                         #endif
129         #endif
130
131                 #if 0
132                 case 4:
133                         printk("Beginning Tests\n");
134                         test_run_measurements(progress-1);  // should never return
135                         break;
136                 case 5:
137                         envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
138                         envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
139                         smp_call_function_single(1, run_env_handler, envs[0], 0);
140                         smp_call_function_single(2, run_env_handler, envs[1], 0);
141                 case 6:
142                 #endif
143                 case 4:
144                         /*
145                         test_smp_call_functions();
146                         test_checklists();
147                         test_barrier();
148                         test_print_info();
149                         test_lapic_status_bit();
150                         test_ipi_sending();
151                         test_pit();
152                         */
153                 case 5:
154                 case 6:
155                 case 7:
156                 case 8:
157                 case 9:
158                 case 10:
159                 case 11:
160                 case 12:
161                 case 13:
162                 case 14:
163                         //test_run_measurements(progress-1);
164                 default:
165                         printk("Manager Progress: %d\n", progress);
166                         // delay if you want to test rescheduling an MCP that yielded
167                         //udelay(15000000);
168                         schedule();
169         }
170         panic("If you see me, then you probably screwed up");
171
172         /*
173         printk("Servicing syscalls from Core 0:\n\n");
174         while (1) {
175                 process_generic_syscalls(&envs[0], 1);
176                 cpu_relax();
177         }
178         */
179         return;
180 }