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