Removed the workqueue
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 23 Mar 2010 01:00:43 +0000 (18:00 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:40 +0000 (17:35 -0700)
And the run_env_handler().  Workqueue functionality should use routine
k_msgs.  Some old tests were removed, which might be of interest to
someone doing measurement stuff.

kern/include/env.h
kern/include/smp.h
kern/include/trap.h
kern/include/workqueue.h [deleted file]
kern/src/Makefrag
kern/src/env.c
kern/src/manager.c
kern/src/testing.c
kern/src/workqueue.c [deleted file]

index a7eb636..fb401ba 100644 (file)
@@ -83,12 +83,4 @@ int          env_user_mem_walk(env_t* e, void* start, size_t len, mem_walk_callback_t ca
 // The following three functions do not return
 void   env_pop_tf(trapframe_t *tf) __attribute__((noreturn));
 
-
-/* Helper handler for smp_call to dispatch jobs to other cores */
-#ifdef __IVY__
-void run_env_handler(trapframe_t *tf, env_t * data);
-#else
-void run_env_handler(trapframe_t *tf, void * data);
-#endif
-
 #endif // !ROS_KERN_ENV_H
index a0f2b35..a05062b 100644 (file)
@@ -15,7 +15,6 @@
 #include <trap.h>
 #include <atomic.h>
 #include <process.h>
-#include <workqueue.h>
 
 #ifdef __SHARC__
 typedef sharC_env_t;
@@ -26,7 +25,6 @@ struct per_cpu_info {
        struct proc *cur_proc;
        trapframe_t *cur_tf;
        bool preempt_pending;
-       struct workqueue NTPTV(t) workqueue;
 
 #ifdef __SHARC__
        // held spin-locks. this will have to go elsewhere if multiple kernel
index 5ab671b..1ac153e 100644 (file)
@@ -42,10 +42,11 @@ extern void sysenter_handler();
  *
  * These are different (for now) than the smp_calls in smp.h, since
  * they will be executed immediately (for urgent messages), and in the order in
- * which they are sent.  smp_calls are currently not run in order, and if they
- * put things on the workqueue, they don't get run until smp_idle (for now).
+ * which they are sent.  smp_calls are currently not run in order, and they must
+ * return (possibly passing the work to a workqueue, which is really just a
+ * routine message, so they really need to just return).
  *
- * Eventually, smp_call and the workqueue will be replaced by these.
+ * Eventually, smp_call will be replaced by these.
  *
  * Also, a big difference is that smp_calls can use the same message (registered
  * in the interrupt_handlers[] for x86) for every recipient, but the kernel
diff --git a/kern/include/workqueue.h b/kern/include/workqueue.h
deleted file mode 100644 (file)
index ebff971..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2009 The Regents of the University of California
- * Barret Rhoden <brho@cs.berkeley.edu>
- * See LICENSE for details.
- *
- * Workqueue: This is a todo list of func, void* that get executed whenever
- * process_workqueue is called.  Typically, this is called from smp_idle().
- * Note that every core will run this, so be careful with dynamic memory mgmt.
- */
-
-#ifndef ROS_KERN_WORKQUEUE_H
-#define ROS_KERN_WORKQUEUE_H
-
-#include <sys/queue.h>
-#include <ros/common.h>
-#include <env.h>
-
-typedef void (*func_t)(TV(t) data);
-struct work {
-       LIST_ENTRY(work) work_link;
-       func_t func;
-       TV(t) data;
-};
-
-// TODO make these dynamic and hold more than 1.  might want better list macros.
-#define WORKQUEUE_ELEMENTS 1
-struct workqueue {
-       struct work TP(TV(t)) statics[WORKQUEUE_ELEMENTS];
-};
-
-void process_workqueue(void);
-// For now, the caller should free their struct work after this call
-int enqueue_work(struct workqueue TP(TV(t)) *queue, struct work TP(TV(t)) *job);
-
-#endif /* ROS_KERN_WORKQUEUE_H */
index 36c3da5..0311fb8 100644 (file)
@@ -22,7 +22,6 @@ KERN_SRCFILES := $(KERN_ARCH_SRCFILES) \
                  $(KERN_SRC_DIR)/readline.c \
                  $(KERN_SRC_DIR)/string.c \
                  $(KERN_SRC_DIR)/atomic.c \
-                 $(KERN_SRC_DIR)/workqueue.c \
                  $(KERN_SRC_DIR)/colored_caches.c \
                  $(KERN_SRC_DIR)/page_alloc.c \
                  $(KERN_SRC_DIR)/pmap.c \
index 3c6ca00..45ea809 100644 (file)
@@ -267,35 +267,6 @@ type SLOCKED(name##_lock) *\
        }\
 }
 
-/* This is the top-half of an interrupt handler, where the bottom half is
- * proc_run (which never returns).  Just add it to the delayed work queue,
- * which (incidentally) can only hold one item at this point.
- *
- * Note this is rather old, and meant to run a RUNNABLE_S on a worker core.
- */
-#ifdef __IVY__
-void run_env_handler(trapframe_t *tf, env_t * data)
-#else
-void run_env_handler(trapframe_t *tf, void * data)
-#endif
-{
-       assert(data);
-       struct work TP(env_t *) job;
-       struct workqueue TP(env_t *) *CT(1) workqueue =
-           TC(&per_cpu_info[core_id()].workqueue);
-       // this doesn't work, and making it a TP(env_t) is wrong
-       // zra: When you want to use other types, let me know, and I can help
-    // make something that Ivy is happy with. 
-#ifdef __IVY__
-       job.func = proc_run;
-#else
-       job.func = (func_t)proc_run;
-#endif
-       job.data = data;
-       if (enqueue_work(workqueue, &job))
-               panic("Failed to enqueue work!");
-}
-
 /* Frees (decrefs) all memory mapped in the given range */
 void env_user_mem_free(env_t* e, void* start, size_t len)
 {
index ee3c62d..6743f63 100644 (file)
@@ -21,7 +21,6 @@
 #include <manager.h>
 #include <process.h>
 #include <schedule.h>
-#include <workqueue.h>
 #include <syscall.h>
 #include <testing.h>
 #include <kfs.h>
@@ -121,28 +120,6 @@ void manager_brho(void)
                        break;
                        #endif
                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:
-               #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,17 +129,6 @@ 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);
                        // delay if you want to test rescheduling an MCP that yielded
index 8967c02..ff03780 100644 (file)
@@ -560,142 +560,6 @@ void test_lapic_status_bit(void)
 }
 #endif // __i386__
 
-/******************************************************************************/
-/*            Test Measurements: Couples with measurement.c                   */
-// All user processes can R/W the UGDATA page
-barrier_t*COUNT(1) bar = (barrier_t*COUNT(1))TC(UGDATA);
-uint32_t*COUNT(1) job_to_run = (uint32_t*COUNT(1))TC(UGDATA + sizeof(barrier_t));
-env_t* env_batch[64]; // Fairly arbitrary, just the max I plan to use.
-
-/* Helpers for test_run_measurements */
-static void wait_for_all_envs_to_die(void)
-{
-       while (atomic_read(&num_envs))
-               cpu_relax();
-}
-
-// this never returns.
-static void sync_tests(int start_core, int num_threads, int job_num)
-{
-       assert(start_core + num_threads <= num_cpus);
-       wait_for_all_envs_to_die();
-       for (int i = start_core; i < start_core + num_threads; i++)
-               env_batch[i] = kfs_proc_create(kfs_lookup_path("roslib_measurements"));
-       lcr3(env_batch[start_core]->env_cr3);
-       init_barrier(bar, num_threads);
-       *job_to_run = job_num;
-       for (int i = start_core; i < start_core + num_threads; i++)
-               smp_call_function_single(i, run_env_handler, env_batch[i], 0);
-       process_workqueue();
-       // we want to fake a run, to reenter manager for the next case
-       env_t *env = kfs_proc_create(kfs_lookup_path("roslib_null"));
-       smp_call_function_single(0, run_env_handler, env, 0);
-       // Note we are still holding references to all the processes
-       process_workqueue();
-       panic("whoops!\n");
-}
-
-static void async_tests(int start_core, int num_threads, int job_num)
-{
-       int count;
-
-       assert(start_core + num_threads <= num_cpus);
-       wait_for_all_envs_to_die();
-       for (int i = start_core; i < start_core + num_threads; i++)
-               env_batch[i] = kfs_proc_create(kfs_lookup_path("roslib_measurements"));
-       printk("async_tests: checkpoint 0\n");
-       lcr3(env_batch[start_core]->env_cr3);
-       init_barrier(bar, num_threads);
-       printk("async_tests: checkpoint 1\n");
-       *job_to_run = job_num;
-       for (int i = start_core; i < start_core + num_threads; i++)
-               smp_call_function_single(i, run_env_handler, env_batch[i], 0);
-       count = 0;
-       while (count > -num_threads) {
-               count = 0;
-               for (int i = start_core; i < start_core + num_threads; i++) {
-                       count += process_generic_syscalls(env_batch[i], 1);
-               }
-               cpu_relax();
-       }
-       // we want to fake a run, to reenter manager for the next case
-       env_t *env = kfs_proc_create(kfs_lookup_path("roslib_null"));
-       smp_call_function_single(0, run_env_handler, env, 0);
-       // Note we are still holding references to all the processes
-       process_workqueue();
-       // this all never returns
-       panic("whoops!\n");
-}
-
-void test_run_measurements(uint32_t job_num)
-{
-       switch (job_num) {
-               case 0: // Nulls
-                       printk("Case 0:\n");
-                       async_tests(2, 1, job_num);  // start core 2, 1 core total
-                       break;
-               case 1: // Sync
-                       printk("Case 1:\n");
-                       sync_tests(2, 1, job_num);
-                       break;
-               case 2:
-                       printk("Case 2:\n");
-                       sync_tests(2, 2, job_num);
-                       break;
-               case 3:
-                       printk("Case 3:\n");
-                       sync_tests(0, 3, job_num);
-                       break;
-               case 4:
-                       printk("Case 4:\n");
-                       sync_tests(0, 4, job_num);
-                       break;
-               case 5:
-                       printk("Case 5:\n");
-                       sync_tests(0, 5, job_num);
-                       break;
-               case 6:
-                       printk("Case 6:\n");
-                       sync_tests(0, 6, job_num);
-                       break;
-               case 7:
-                       printk("Case 7:\n");
-                       sync_tests(0, 7, job_num);
-                       break;
-               case 8:
-                       printk("Case 8:\n");
-                       sync_tests(0, 8, job_num);
-                       break;
-               case 9:
-                       printk("Case 9:\n");
-                       async_tests(2, 1, job_num);
-                       break;
-               case 10:
-                       printk("Case 10:\n");
-                       async_tests(2, 2, job_num);
-                       break;
-               case 11:
-                       printk("Case 11:\n");
-                       async_tests(2, 3, job_num);
-                       break;
-               case 12:
-                       printk("Case 12:\n");
-                       async_tests(2, 4, job_num);
-                       break;
-               case 13:
-                       printk("Case 13:\n");
-                       async_tests(2, 5, job_num);
-                       break;
-               case 14:
-                       printk("Case 14:\n");
-                       async_tests(2, 6, job_num);
-                       break;
-               default:
-                       warn("Invalid test number!!");
-       }
-       panic("Error in test setup!!");
-}
-
 /************************************************************/
 /* ISR Handler Functions */
 
diff --git a/kern/src/workqueue.c b/kern/src/workqueue.c
deleted file mode 100644 (file)
index 8d525ae..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2009 The Regents of the University of California
- * Barret Rhoden <brho@cs.berkeley.edu>
- * See LICENSE for details.
- */
-
-#ifdef __SHARC__
-#pragma nosharc
-#endif
-
-#include <atomic.h>
-#include <smp.h>
-
-#include <error.h>
-
-#include <atomic.h>
-#include <stdio.h>
-#include <workqueue.h>
-
-/*
- * TODO: actually use a queue, which will change some things all over.
- */
-void process_workqueue()
-{
-       struct work TP(TV(t)) work;
-       per_cpu_info_t *cpuinfo = &per_cpu_info[core_id()];
-
-       // copy the work in, since we may never return to this stack frame
-       spin_lock_irqsave(&cpuinfo->lock);
-       work = cpuinfo->workqueue.statics[0];
-       spin_unlock_irqsave(&cpuinfo->lock);
-       if (work.func) {
-               // TODO: possible race with this.  sort it out when we have a queue.
-               spin_lock_irqsave(&cpuinfo->lock);
-               cpuinfo->workqueue.statics[0].func = 0;
-               spin_unlock_irqsave(&cpuinfo->lock);
-               // We may never return from this (if it is proc_run)
-               work.func(work.data);
-       }
-}
-
-int enqueue_work(struct workqueue TP(TV(t)) *queue, struct work TP(TV(t)) *job)
-{
-       error_t retval = 0;
-       per_cpu_info_t *cpuinfo = &per_cpu_info[core_id()];
-
-       spin_lock_irqsave(&cpuinfo->lock);
-       printd("Enqueuing func 0x%08x and data 0x%08x on core %d.\n",
-              job->func, job->data, core_id());
-       if (queue->statics[0].func)
-               retval = -ENOMEM;
-       else
-               queue->statics[0] = *job;
-       spin_unlock_irqsave(&cpuinfo->lock);
-       return retval;
-}