Proc state work: WAITING helpers and is_mcp helper
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 16 Sep 2011 00:06:16 +0000 (17:06 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:07 +0000 (17:36 -0700)
The __proc_wakeup() function can be called whether the process is
WAITING or not - it doesn't particularly care.

Instead of having multiple WAITING states, I'm going with the is_mcp
bool.  This simplifies event code and other places that don't care about
the _M nature of the process.  We'll see if this is a good idea or not.
I might slim down the other states as well, though those seem to work
well with the switch statements.

kern/include/env.h
kern/include/process.h
kern/src/process.c
kern/src/resource.c

index 55df6e6..65ae839 100644 (file)
@@ -34,6 +34,7 @@ struct proc {
        pid_t ppid;                 // Parent's PID
        pid_t exitcode;                         // exit() param or main() return value
        uint32_t state;                         // Status of the process
+       bool is_mcp;                    /* is in multi mode */
        struct kref p_kref;             /* Refcnt */
        uint32_t env_flags;
        uintptr_t env_entry;
index c5123d3..3eac075 100644 (file)
@@ -83,6 +83,8 @@ void proc_destroy(struct proc *SAFE p);
 void __proc_yield_s(struct proc *p, struct trapframe *tf);
 void proc_yield(struct proc *SAFE p, bool being_nice);
 void proc_notify(struct proc *p, uint32_t vcoreid);
+void __proc_wakeup(struct proc *p);
+bool __proc_is_mcp(struct proc *p);
 
 /* Vcoremap info: */
 uint32_t proc_get_vcoreid(struct proc *SAFE p, uint32_t pcoreid);
index 3521949..e360391 100644 (file)
@@ -111,7 +111,9 @@ int __proc_set_state(struct proc *p, uint32_t state)
         * RBS -> RGS
         * RGS -> RBS
         * RGS -> W
+        * RGM -> W
         * W   -> RBS
+        * W   -> RBM
         * RGS -> RBM
         * RBM -> RGM
         * RGM -> RBM
@@ -139,7 +141,7 @@ int __proc_set_state(struct proc *p, uint32_t state)
                                panic("Invalid State Transition! PROC_RUNNING_S to %02x", state);
                        break;
                case PROC_WAITING:
-                       if (state != PROC_RUNNABLE_S)
+                       if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M)))
                                panic("Invalid State Transition! PROC_WAITING to %02x", state);
                        break;
                case PROC_DYING:
@@ -151,7 +153,8 @@ int __proc_set_state(struct proc *p, uint32_t state)
                                panic("Invalid State Transition! PROC_RUNNABLE_M to %02x", state);
                        break;
                case PROC_RUNNING_M:
-                       if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_DYING)))
+                       if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_WAITING |
+                                      PROC_DYING)))
                                panic("Invalid State Transition! PROC_RUNNING_M to %02x", state);
                        break;
        }
@@ -306,6 +309,7 @@ error_t proc_alloc(struct proc **pp, struct proc *parent)
        p->exitcode = 1337;     /* so we can see processes killed by the kernel */
        p->ppid = parent ? parent->pid : 0;
        p->state = PROC_CREATED; /* shouldn't go through state machine for init */
+       p->is_mcp = FALSE;
        p->env_flags = 0;
        p->env_entry = 0; // cheating.  this really gets set later
        p->heap_top = (void*)UTEXT;     /* heap_bottom set in proc_init_procinfo */
@@ -907,6 +911,27 @@ void proc_notify(struct proc *p, uint32_t vcoreid)
        }
 }
 
+/* Hold the lock before calling this.  If the process is WAITING, it will wake
+ * it up and schedule it. */
+void __proc_wakeup(struct proc *p)
+{
+       if (p->state != PROC_WAITING)
+               return;
+       if (__proc_is_mcp(p))
+               __proc_set_state(p, PROC_RUNNABLE_M);
+       else
+               __proc_set_state(p, PROC_RUNNABLE_S);
+       schedule_proc(p);
+}
+
+/* Is the process in multi_mode / is an MCP or not?  */
+bool __proc_is_mcp(struct proc *p)
+{
+       /* in lieu of using the amount of cores requested, or having a bunch of
+        * states (like PROC_WAITING_M and _S), I'll just track it with a bool. */
+       return p->is_mcp;
+}
+
 /************************  Preemption Functions  ******************************
  * Don't rely on these much - I'll be sure to change them up a bit.
  *
@@ -1612,7 +1637,7 @@ void print_proc_info(pid_t pid)
        printk("struct proc: %p\n", p);
        printk("PID: %d\n", p->pid);
        printk("PPID: %d\n", p->ppid);
-       printk("State: 0x%08x\n", p->state);
+       printk("State: 0x%08x (%s)\n", p->state, p->is_mcp ? "M" : "S");
        printk("Refcnt: %d\n", atomic_read(&p->p_kref.refcount) - 1);
        printk("Flags: 0x%08x\n", p->env_flags);
        printk("CR3(phys): 0x%08x\n", p->env_cr3);
index 2f434ce..a662344 100644 (file)
@@ -142,6 +142,7 @@ ssize_t core_request(struct proc *p)
                                need_to_idle = TRUE;
                                // change to runnable_m (it's TF is already saved)
                                __proc_set_state(p, PROC_RUNNABLE_M);
+                               p->is_mcp = TRUE;
                                break;
                        case (PROC_RUNNABLE_S):
                                /* Issues: being on the runnable_list, proc_set_state not liking