9ns: Fix dangling negative TFs
[akaros.git] / kern / src / manager.c
index 735dd66..a5d5766 100644 (file)
@@ -4,23 +4,27 @@
  * 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 <kmalloc.h>
 #include <assert.h>
 #include <manager.h>
 #include <process.h>
 #include <schedule.h>
-#include <workqueue.h>
 #include <syscall.h>
-#include <testing.h>
-#include <kfs.h>
+#include <ktest.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>
 
 /*
  * Currently, if you leave this function by way of proc_run (process_workqueue
  */
 void manager(void)
 {
+       // LoL
+       #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
 
-       // LoL
-       #define PASTE(s1,s2) s1 ## s2
-       #define MANAGER_FUNC(dev) PASTE(manager_,dev)
-
        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();
@@ -152,24 +196,14 @@ void manager_brho(void)
                        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");
@@ -179,98 +213,79 @@ void manager_brho(void)
        }
        */
        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");
 }