Events that wake processes poke the ksched
authorBarret Rhoden <brho@cs.berkeley.edu>
Sun, 11 Mar 2012 17:47:57 +0000 (10:47 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sun, 11 Mar 2012 17:47:57 +0000 (10:47 -0700)
Previously, the processes would wake up, but wouldn't tell the ksched.
The ksched would have to notice on its next tick, which could be 10ms
away (current ksched), or never (tickless kscheds).  For block_test,
which sleeps 5ms per loop, without this patch, you'd wait close to 5ms
til the next timer tick.  This patch cuts down block test to about
5.5sec (poke to run when avail), instead of 10sec (run on timer tick).

Unblocking is a big enough deal that it got its own callback, but we're
not using it for anything other than a RES_CORES poke right now.

kern/include/schedule.h
kern/src/event.c
kern/src/process.c
kern/src/schedule.c
tests/block_test.c

index 6168fd8..9b87499 100644 (file)
@@ -28,11 +28,16 @@ void register_mcp(struct proc *p);
  * ever call this directly. */
 void schedule(void);
 
-/* Proc p's resource desires changed, it recently became RUNNABLE, or something
- * in general that would lead to a new decision.  The process can directly poke
- * the ksched via a syscall, so be careful of abuse. */
+/* Proc p's resource desires changed, or something in general that would lead to
+ * a new decision.  The process can directly poke the ksched via a syscall, so
+ * be careful of abuse. */
 void poke_ksched(struct proc *p, int res_type);
 
+/* Proc p just woke up (due to an event).  This is a more specific case than
+ * poke_ksched(), in case kscheds want to do some accounting or something more
+ * than just giving it cores. */
+void ksched_proc_unblocked(struct proc *p);
+
 /* The calling cpu/core has nothing to do and plans to idle/halt.  This is an
  * opportunity to pick the nature of that halting (low power state, etc), or
  * provide some other work (_Ss on LL cores). */
index 9003041..257852c 100644 (file)
@@ -15,6 +15,7 @@
 #include <stdio.h>
 #include <assert.h>
 #include <pmap.h>
+#include <schedule.h>
 
 /* Userspace could give us a vcoreid that causes us to compute a vcpd that is
  * outside procdata.  If we hit UWLIM, then we've gone farther than we should.
@@ -242,6 +243,7 @@ static void spam_public_msg(struct proc *p, struct event_msg *ev_msg,
                                spin_lock(&p->proc_lock);
                                __proc_wakeup(p);       /* internally, this double-checks WAITING */
                                spin_unlock(&p->proc_lock);
+                               ksched_proc_unblocked(p);
                        }
                        return;
                }
@@ -289,6 +291,7 @@ ultimate_fallback:
         * __proc_wakeup() will check for WAITING. */
        __proc_wakeup(p);
        spin_unlock(&p->proc_lock);
+       ksched_proc_unblocked(p);
        return;
 }
 
index ab6ad77..39d527f 100644 (file)
@@ -1006,7 +1006,6 @@ void __proc_wakeup(struct proc *p)
                if (!p->procdata->res_req[RES_CORES].amt_wanted)
                        p->procdata->res_req[RES_CORES].amt_wanted = 1;
                __proc_set_state(p, PROC_RUNNABLE_M);
-               /* TODO: consider poke_ksched() here */
        } else {
                printk("[kernel] FYI, waking up an _S proc\n");
                __proc_set_state(p, PROC_RUNNABLE_S);
index 64cbc3b..30a3b7b 100644 (file)
@@ -222,6 +222,13 @@ void poke_ksched(struct proc *p, int res_type)
        spin_unlock(&sched_lock);
 }
 
+/* Proc p just woke up (due to an event).  Our dumb ksched will just try to deal
+ * with its core desires. */
+void ksched_proc_unblocked(struct proc *p)
+{
+       poke_ksched(p, RES_CORES);
+}
+
 /* The calling cpu/core has nothing to do and plans to idle/halt.  This is an
  * opportunity to pick the nature of that halting (low power state, etc), or
  * provide some other work (_Ss on LL cores).  Note that interrupts are
index 81cb934..a7d057d 100644 (file)
@@ -30,6 +30,10 @@ void *block_thread(void* arg)
 
 int main(int argc, char** argv) 
 {
+       struct timeval tv = {0};
+       if (gettimeofday(&tv, 0))
+               perror("Time error...");
+       printf("Start time: %dsec %dusec\n", tv.tv_sec, tv.tv_usec);
        for (int i = 0; i < NUM_TEST_THREADS; i++) {
                printf_safe("[A] About to create thread %d\n", i);
                pthread_create(&my_threads[i], NULL, &block_thread, NULL);
@@ -40,5 +44,8 @@ int main(int argc, char** argv)
                printf_safe("[A] Successfully joined on thread %d (retval: %p)\n", i,
                            my_retvals[i]);
        }
+       if (gettimeofday(&tv, 0))
+               perror("Time error...");
+       printf("End time  : %dsec %dusec\n", tv.tv_sec, tv.tv_usec);
        printf("All done, exiting cleanishly\n");
 }