Cleans up proc_preempt_core()
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 1 May 2012 18:16:28 +0000 (11:16 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 5 Sep 2012 21:43:56 +0000 (14:43 -0700)
It's now the caller's responsibility to do something with the idle core.

kern/include/process.h
kern/src/monitor.c
kern/src/process.c

index 4851560..9a4ea82 100644 (file)
@@ -115,7 +115,7 @@ void __proc_preempt_warn(struct proc *p, uint32_t vcoreid, uint64_t when);
 void __proc_preempt_warnall(struct proc *p, uint64_t when);
 void __proc_preempt_core(struct proc *p, uint32_t pcoreid);
 uint32_t __proc_preempt_all(struct proc *p, uint32_t *pc_arr);
-void proc_preempt_core(struct proc *p, uint32_t pcoreid, uint64_t usec);
+bool proc_preempt_core(struct proc *p, uint32_t pcoreid, uint64_t usec);
 void proc_preempt_all(struct proc *p, uint64_t usec);
 
 /* Current / cr3 / context management */
index 2856329..a50b229 100644 (file)
@@ -527,9 +527,13 @@ int mon_measure(int argc, char *NTS *NT COUNT(argc) argv, trapframe_t *tf)
                if (argc == 4) { /* single core being preempted, warned but no delay */
                        uint32_t pcoreid = strtol(argv[3], 0, 0);
                        begin = start_timing();
-                       proc_preempt_core(p, pcoreid, 1000000); // 1 sec warning
-                       /* done when unmapped (right before abandoning) */
-                       spin_on(p->procinfo->pcoremap[pcoreid].valid);
+                       if (proc_preempt_core(p, pcoreid, 1000000)) {
+                               put_idle_core(p, pcoreid);
+                               /* done when unmapped (right before abandoning) */
+                               spin_on(p->procinfo->pcoremap[pcoreid].valid);
+                       } else {
+                               printk("Core %d was not mapped to proc\n", pcoreid);
+                       }
                        diff = stop_timing(begin);
                } else { /* preempt all cores, warned but no delay */
                        end_refcnt = kref_refcnt(&p->p_kref) - p->procinfo->num_vcores;
index f655f5f..bafe543 100644 (file)
@@ -1221,30 +1221,28 @@ uint32_t __proc_preempt_all(struct proc *p, uint32_t *pc_arr)
 }
 
 /* Warns and preempts a vcore from p.  No delaying / alarming, or anything.  The
- * warning will be for u usec from now. */
-void proc_preempt_core(struct proc *p, uint32_t pcoreid, uint64_t usec)
+ * warning will be for u usec from now.  Returns TRUE if the core belonged to
+ * the proc (and thus preempted), False if the proc no longer has the core. */
+bool proc_preempt_core(struct proc *p, uint32_t pcoreid, uint64_t usec)
 {
        uint64_t warn_time = read_tsc() + usec2tsc(usec);
-       bool preempted = FALSE;
-       /* DYING could be okay */
+       bool retval = FALSE;
        if (p->state != PROC_RUNNING_M) {
+               /* more of an FYI for brho.  should be harmless to just return. */
                warn("Tried to preempt from a non RUNNING_M proc!");
-               return;
+               return FALSE;
        }
        spin_lock(&p->proc_lock);
        if (is_mapped_vcore(p, pcoreid)) {
                __proc_preempt_warn(p, get_vcoreid(p, pcoreid), warn_time);
                __proc_preempt_core(p, pcoreid);
-               preempted = TRUE;
-       } else {
-               warn("Pcore doesn't belong to the process!!");
-       }
-       if (!p->procinfo->num_vcores) {
-               __proc_set_state(p, PROC_RUNNABLE_M);
+               /* we might have taken the last core */
+               if (!p->procinfo->num_vcores)
+                       __proc_set_state(p, PROC_RUNNABLE_M);
+               retval = TRUE;
        }
        spin_unlock(&p->proc_lock);
-       if (preempted)
-               put_idle_core(p, pcoreid);
+       return retval;
 }
 
 /* Warns and preempts all from p.  No delaying / alarming, or anything.  The