* See LICENSE for details.
*/
-#ifdef __SHARC__
-#pragma nosharc
-#endif
#include <ros/common.h>
#include <smp.h>
+#include <arch/init.h>
+#include <mm.h>
+#include <elf.h>
+#include <frontend.h>
+#include <kmalloc.h>
#include <assert.h>
#include <manager.h>
#include <process.h>
#include <schedule.h>
-#include <workqueue.h>
#include <syscall.h>
-#include <testing.h>
+#include <ktest.h>
#include <kfs.h>
#include <stdio.h>
-#include <timing.h>
+#include <time.h>
+#include <monitor.h>
+#include <string.h>
+#include <pmap.h>
+#include <arch/console.h>
+#include <time.h>
+#include <ros/arch/membar.h>
/*
* Currently, if you leave this function by way of proc_run (process_workqueue
*/
void manager(void)
{
- #ifndef DEVELOPER_NAME
- #define DEVELOPER_NAME brho
- #endif
-
// LoL
#define PASTE(s1,s2) s1 ## s2
#define MANAGER_FUNC(dev) PASTE(manager_,dev)
+ #if !defined(DEVELOPER_NAME) && \
+ (defined(CONFIG_KERNEL_TESTING) || \
+ defined(CONFIG_USERSPACE_TESTING))
+ #define DEVELOPER_NAME jenkins
+ #endif
+
+ #ifndef DEVELOPER_NAME
+ #define DEVELOPER_NAME brho
+ #endif
+
void MANAGER_FUNC(DEVELOPER_NAME)(void);
MANAGER_FUNC(DEVELOPER_NAME)();
}
+char *p_argv[] = {0, 0, 0};
+/* Helper macro for quickly running a process. Pass it a string, *file, and a
+ * *proc. */
+#define quick_proc_run(x, p, f) \
+ (f) = do_file_open((x), O_READ, 0); \
+ assert((f)); \
+ p_argv[0] = file_name((f)); \
+ (p) = proc_create((f), p_argv, NULL); \
+ kref_put(&(f)->f_kref); \
+ spin_lock(&(p)->proc_lock); \
+ __proc_set_state((p), PROC_RUNNABLE_S); \
+ spin_unlock(&(p)->proc_lock); \
+ proc_run_s((p)); \
+ proc_decref((p));
+
+#define quick_proc_create(x, p, f) \
+ (f) = do_file_open((x), O_READ, 0); \
+ assert((f)); \
+ p_argv[0] = file_name((f)); \
+ (p) = proc_create((f), p_argv, NULL); \
+ kref_put(&(f)->f_kref); \
+ spin_lock(&(p)->proc_lock); \
+ __proc_set_state((p), PROC_RUNNABLE_S); \
+ spin_unlock(&(p)->proc_lock);
+
+#define quick_proc_color_run(x, p, c, f) \
+ (f) = do_file_open((x), O_READ, 0); \
+ assert((f)); \
+ p_argv[0] = file_name((f)); \
+ (p) = proc_create((f), p_argv, NULL); \
+ kref_put(&(f)->f_kref); \
+ spin_lock(&(p)->proc_lock); \
+ __proc_set_state((p), PROC_RUNNABLE_S); \
+ spin_unlock(&(p)->proc_lock); \
+ p->cache_colors_map = cache_colors_map_alloc(); \
+ for (int i = 0; i < (c); i++) \
+ cache_color_alloc(llc_cache, p->cache_colors_map); \
+ proc_run_s((p)); \
+ proc_decref((p));
+
+#define quick_proc_color_create(x, p, c, f) \
+ (f) = do_file_open((x), O_READ, 0); \
+ assert((f)); \
+ p_argv[0] = file_name((f)); \
+ (p) = proc_create((f), p_argv, NULL); \
+ kref_put(&(f)->f_kref); \
+ spin_lock(&(p)->proc_lock); \
+ __proc_set_state((p), PROC_RUNNABLE_S); \
+ spin_unlock(&(p)->proc_lock); \
+ p->cache_colors_map = cache_colors_map_alloc(); \
+ for (int i = 0; i < (c); i++) \
+ cache_color_alloc(llc_cache, p->cache_colors_map);
+
void manager_brho(void)
{
- static uint8_t RACY progress = 0;
+ static bool first = TRUE;
+ struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
- static struct proc *envs[256];
- static struct proc *p ;
+ if (first) {
+ printk("*** IRQs must be enabled for input emergency codes ***\n");
+ #ifdef CONFIG_X86
+ printk("*** Hit ctrl-g to enter the monitor. ***\n");
+ printk("*** Hit ctrl-q to force-enter the monitor. ***\n");
+ printk("*** Hit ctrl-b for a backtrace of core 0 ***\n");
+ #else
+ printk("*** Hit ctrl-g to enter the monitor. ***\n");
+ #warning "***** ctrl-g untested on riscv, check k/a/r/trap.c *****"
+ #endif
+ first = FALSE;
+ }
+ /* just idle, and deal with things via interrupts. or via face. */
+ smp_idle();
+ /* whatever we do in the manager, keep in mind that we need to not do
+ * anything too soon (like make processes), since we'll drop in here during
+ * boot if the boot sequence required any I/O (like EXT2), and we need to
+ * PRKM() */
+ assert(0);
- uint32_t corelist[MAX_NUM_CPUS];
+#if 0 /* ancient tests below: (keeping around til we ditch the manager) */
+ // for testing taking cores, check in case 1 for usage
+ uint32_t corelist[MAX_NUM_CORES];
uint32_t num = 3;
+ struct file *temp_f;
+ static struct proc *p;
+ static uint8_t RACY progress = 0; /* this will wrap around. */
switch (progress++) {
case 0:
- //p = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
- p = kfs_proc_create(kfs_lookup_path("roslib_mhello"));
- // being proper and all:
- spin_lock_irqsave(&p->proc_lock);
- proc_set_state(p, PROC_RUNNABLE_S);
- // normal single-cored way
- spin_unlock_irqsave(&p->proc_lock);
- proc_run(p);
+ printk("Top of the manager to ya!\n");
+ /* 124 is half of the available boxboro colors (with the kernel
+ * getting 8) */
+ //quick_proc_color_run("msr_dumb_while", p, 124, temp_f);
+ quick_proc_run("/bin/hello", p, temp_f);
#if 0
// this is how you can transition to a parallel process manually
// make sure you don't proc run first
- proc_set_state(p, PROC_RUNNING_S);
- proc_set_state(p, PROC_RUNNABLE_M);
+ __proc_set_state(p, PROC_RUNNING_S);
+ __proc_set_state(p, PROC_RUNNABLE_M);
p->resources[RES_CORES].amt_wanted = 5;
- spin_unlock_irqsave(&p->proc_lock);
+ spin_unlock(&p->proc_lock);
core_request(p);
panic("This is okay");
#endif
break;
case 1:
#if 0
- panic("This is okay");
udelay(10000000);
- printk("taking 3 cores from p\n");
- for (int i = 0; i < num; i++)
- corelist[i] = 7-i; // 7, 6, and 5
- spin_lock_irqsave(&p->proc_lock);
- proc_take_cores(p, corelist, &num, __death);
- spin_unlock_irqsave(&p->proc_lock);
- udelay(5000000);
- printk("Killing p\n");
- proc_destroy(p);
- printk("Killed p\n");
- udelay(1000000);
+ // this is a ghetto way to test restarting an _M
+ printk("\nattempting to ghetto preempt...\n");
+ spin_lock(&p->proc_lock);
+ proc_take_allcores(p, __death);
+ __proc_set_state(p, PROC_RUNNABLE_M);
+ spin_unlock(&p->proc_lock);
+ udelay(5000000);
+ printk("\nattempting to restart...\n");
+ core_request(p); // proc still wants the cores
+ panic("This is okay");
+ // this tests taking some cores, and later killing an _M
+ printk("taking 3 cores from p\n");
+ for (int i = 0; i < num; i++)
+ corelist[i] = 7-i; // 7, 6, and 5
+ spin_lock(&p->proc_lock);
+ proc_take_cores(p, corelist, &num, __death);
+ spin_unlock(&p->proc_lock);
+ udelay(5000000);
+ printk("Killing p\n");
+ proc_destroy(p);
+ printk("Killed p\n");
panic("This is okay");
envs[0] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
- proc_set_state(envs[0], PROC_RUNNABLE_S);
+ __proc_set_state(envs[0], PROC_RUNNABLE_S);
proc_run(envs[0]);
+ warn("DEPRECATED");
break;
#endif
- #ifdef __i386__
- case 2:
- #if 0
- panic("Do not panic");
- envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
- envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
- smp_call_function_single(1, run_env_handler, envs[0], 0);
- smp_call_function_single(2, run_env_handler, envs[1], 0);
- break;
- #endif
- case 3:
- #else // sparc
case 2:
- panic("Do not panic");
- envs[0] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
- envs[1] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
- envs[2] = kfs_proc_create(kfs_lookup_path("roslib_proctests"));
- envs[3] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
- envs[4] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
- envs[4] = kfs_proc_create(kfs_lookup_path("roslib_fptest"));
- envs[5] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
- envs[6] = kfs_proc_create(kfs_lookup_path("roslib_null"));
- proc_run(envs[0]);
- break;
- case 3:
- #if 0
- // reminder of how to spawn remotely
- for (int i = 0; i < 8; i++) {
- envs[i] = kfs_proc_create(kfs_lookup_path("roslib_hello"));
- proc_set_state(envs[i], PROC_RUNNABLE_S);
- smp_call_function_single(i, run_env_handler, envs[i], 0);
- }
- process_workqueue();
- #endif
- #endif
-
- #if 0
- case 4:
- printk("Beginning Tests\n");
- test_run_measurements(progress-1); // should never return
- break;
- case 5:
- envs[0] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_client"));
- envs[1] = kfs_proc_create(kfs_lookup_path("parlib_channel_test_server"));
- smp_call_function_single(1, run_env_handler, envs[0], 0);
- smp_call_function_single(2, run_env_handler, envs[1], 0);
- case 6:
- #endif
- case 4:
/*
test_smp_call_functions();
test_checklists();
test_ipi_sending();
test_pit();
*/
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- //test_run_measurements(progress-1);
default:
- printk("Manager Progress: %d\n", progress);
+ printd("Manager Progress: %d\n", progress);
// delay if you want to test rescheduling an MCP that yielded
//udelay(15000000);
- schedule();
+ run_scheduler();
}
panic("If you see me, then you probably screwed up");
+ monitor(0);
/*
printk("Servicing syscalls from Core 0:\n\n");
}
*/
return;
+#endif
}
-void manager_klueska()
+void manager_jenkins()
{
- static struct proc *envs[256];
- static uint8_t progress = 0;
+ #ifdef CONFIG_KERNEL_TESTING
+ printk("<-- BEGIN_KERNEL_TESTS -->\n");
+ run_registered_ktest_suites();
+ printk("<-- END_KERNEL_TESTS -->\n");
+ #endif
- if (progress++ == 0) {
- envs[0] = kfs_proc_create(kfs_lookup_path("parlib_matrix"));
- proc_set_state(envs[0], PROC_RUNNABLE_S);
- proc_run(envs[0]);
- }
- schedule();
+ // Run userspace tests (from config specified path).
+ #ifdef CONFIG_USERSPACE_TESTING
+ if (strlen(CONFIG_USERSPACE_TESTING_SCRIPT) != 0) {
+ char exec[] = "/bin/ash";
+ char *p_argv[] = {exec, CONFIG_USERSPACE_TESTING_SCRIPT, 0};
- panic("DON'T PANIC");
+ struct file *program = do_file_open(exec, O_READ, 0);
+ struct proc *p = proc_create(program, p_argv, NULL);
+ proc_wakeup(p);
+ proc_decref(p); /* let go of the reference created in proc_create() */
+ kref_put(&program->f_kref);
+ run_scheduler();
+ // Need a way to wait for p to finish
+ } else {
+ printk("No user-space launcher file specified.\n");
+ }
+ #endif
+ smp_idle();
+ assert(0);
}
-static char*
-itoa(int num, char* buf0, size_t base)
+void manager_klueska()
{
- if(base > 16)
- return NULL;
-
- char* buf = buf0;
- int len = 0, i;
-
- if(num < 0)
- {
- *buf++ = '-';
- num = -num;
- }
-
- do {
- buf[len++] = "0123456789abcdef"[num%base];
- num /= base;
- } while(num);
+ static struct proc *envs[256];
+ static volatile uint8_t progress = 0;
- for(i = 0; i < len/2; i++)
- {
- char temp = buf[i];
- buf[i] = buf[len-i-1];
- buf[len-i-1] = temp;
+ if (progress == 0) {
+ progress++;
+ panic("what do you want to do?");
+ //envs[0] = kfs_proc_create(kfs_lookup_path("fillmeup"));
+ __proc_set_state(envs[0], PROC_RUNNABLE_S);
+ proc_run_s(envs[0]);
+ warn("DEPRECATED");
}
- buf[len] = 0;
+ run_scheduler();
- return buf0;
+ panic("DON'T PANIC");
}
void manager_waterman()
{
- static struct proc *envs[256];
- static uint8_t progress = 0;
- char buf0[32],buf1[32];
+ static bool first = true;
+ if (first)
+ mon_shell(0, 0, 0);
+ smp_idle();
+ assert(0);
+}
- #define RUN_APP(name,nargs,args...) \
- do { \
- envs[progress-1] = kfs_proc_create(kfs_lookup_path(name)); \
- proc_set_state(envs[progress-1], PROC_RUNNABLE_S); \
- if(nargs) proc_init_argc_argv(envs[progress-1],nargs,##args); \
- proc_run(envs[progress-1]); \
- } while(0)
-
+void manager_yuzhu()
+{
- switch(progress++)
- {
- case 0:
- RUN_APP("parlib_draw_nanwan_standalone",0);
- break;
- case 1:
- RUN_APP("parlib_manycore_test",0);
- break;
- case 2:
- RUN_APP("parlib_draw_nanwan_standalone",0);
- break;
- case 3:
- RUN_APP("parlib_pthread_pthread_test",0);
- break;
- case 4:
- RUN_APP("parlib_pthread_blackscholes",3,"blackscholes",itoa(num_cpus>1?num_cpus-1:1,buf0,10),itoa(256,buf1,10));
- break;
+ static uint8_t progress = 0;
+ static struct proc *p;
+
+ // for testing taking cores, check in case 1 for usage
+ uint32_t corelist[MAX_NUM_CORES];
+ uint32_t num = 3;
- //case 5:
- // //while(*(volatile uint32_t*)&envs[4]->state != ENV_FREE);
- // //reboot();
- // break;
+ //create_server(init_num_cores, loop);
- case 5:
- RUN_APP("parlib_matrix",0);
- break;
- }
+ monitor(0);
- schedule();
+ // quick_proc_run("hello", p);
- panic("DON'T PANIC");
}