Refactor to move alloc stuff to corealloc.c (4/7)
authorKevin Klues <klueska@cs.berkeley.edu>
Tue, 29 Sep 2015 00:45:43 +0000 (17:45 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 24 Nov 2015 19:48:50 +0000 (14:48 -0500)
This commit moves the primary logic of the get_any_idle_core(),
get_specific_idle_core(), put_idle_core() functions from schedule.c into
corealloc.c. The 'get' calls are intended to allow external code to extract
idle cores from consideration by the core allocation algorithm.  Once
obtained, the core allocation algorithm forgets about them until they are
reinserted via a call to put_idle_core().

Signed-off-by: Kevin Klues <klueska@cs.berkeley.edu>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/corerequest.h
kern/src/corealloc.c
kern/src/schedule.c

index 8e6b0fd..77be80b 100644 (file)
@@ -43,6 +43,15 @@ void __track_core_dealloc(struct proc *p, uint32_t pcoreid);
 void __track_core_dealloc_bulk(struct proc *p, uint32_t *pc_arr,
                                uint32_t nr_cores);
 
+/* Get/Put an idle core from our pcore list and return its core_id. Don't
+ * consider the chosen core in the future when handing out cores to a
+ * process. This code assumes that the scheduler that uses it holds a lock
+ * for the duration of the call. This will not give out provisioned cores.
+ * The gets return the coreid on success, -1 or -error on failure. */
+int __get_any_idle_core(void);
+int __get_specific_idle_core(int coreid);
+void __put_idle_core(int coreid);
+
 /* Provision a core to proc p. This code assumes that the scheduler that uses
  * it holds a lock for the duration of the call. */
 void __provision_core(struct proc *p, struct sched_pcore *spc);
index 126242b..4ab5d02 100644 (file)
@@ -85,3 +85,65 @@ void __track_core_dealloc_bulk(struct proc *p, uint32_t *pc_arr,
        for (int i = 0; i < nr_cores; i++)
                __track_core_dealloc(p, pc_arr[i]);
 }
+
+/* Get an idle core from our pcore list and return its core_id. Don't
+ * consider the chosen core in the future when handing out cores to a
+ * process. This code assumes that the scheduler that uses it holds a lock
+ * for the duration of the call. This will not give out provisioned cores. */
+int __get_any_idle_core(void)
+{
+       struct sched_pcore *spc;
+       int ret = -1;
+
+       while ((spc = TAILQ_FIRST(&idlecores))) {
+               /* Don't take cores that are provisioned to a process */
+               if (spc->prov_proc)
+                       continue;
+               assert(!spc->alloc_proc);
+               TAILQ_REMOVE(&idlecores, spc, alloc_next);
+               ret = spc2pcoreid(spc);
+               break;
+       }
+       return ret;
+}
+
+/* Detect if a pcore is idle or not. */
+/* TODO: if we end up using this a lot, track CG-idleness as a property of
+ * the SPC instead of doing a linear search. */
+static bool __spc_is_idle(struct sched_pcore *spc)
+{
+       struct sched_pcore *i;
+
+       TAILQ_FOREACH(i, &idlecores, alloc_next) {
+               if (spc == i)
+                       return TRUE;
+       }
+       return FALSE;
+}
+
+/* Same as __get_any_idle_core() except for a specific core id. */
+int __get_specific_idle_core(int coreid)
+{
+       struct sched_pcore *spc = pcoreid2spc(coreid);
+       int ret = -1;
+
+       assert((coreid >= 0) && (coreid < num_cores));
+       if (__spc_is_idle(pcoreid2spc(coreid)) && !spc->prov_proc) {
+               assert(!spc->alloc_proc);
+               TAILQ_REMOVE(&idlecores, spc, alloc_next);
+               ret = coreid;
+       }
+       return ret;
+}
+
+/* Reinsert a core obtained via __get_any_idle_core() or
+ * __get_specific_idle_core() back into the idlecore map. This code assumes
+ * that the scheduler that uses it holds a lock for the duration of the call.
+ * This will not give out provisioned cores. */
+void __put_idle_core(int coreid)
+{
+       struct sched_pcore *spc = pcoreid2spc(coreid);
+
+       assert((coreid >= 0) && (coreid < num_cores));
+       TAILQ_INSERT_TAIL(&idlecores, spc, alloc_next);
+}
index 83d8394..a7ded50 100644 (file)
@@ -513,45 +513,16 @@ void avail_res_changed(int res_type, long change)
 
 int get_any_idle_core(void)
 {
-       struct sched_pcore *spc;
-       int ret = -1;
        spin_lock(&sched_lock);
-       while ((spc = TAILQ_FIRST(&idlecores))) {
-               /* Don't take cores that are provisioned to a process */
-               if (spc->prov_proc)
-                       continue;
-               assert(!spc->alloc_proc);
-               TAILQ_REMOVE(&idlecores, spc, alloc_next);
-               ret = spc2pcoreid(spc);
-               break;
-       }
+       int ret = __get_any_idle_core();
        spin_unlock(&sched_lock);
        return ret;
 }
 
-/* TODO: if we end up using this a lot, track CG-idleness as a property of the
- * SPC instead of doing a linear search. */
-static bool __spc_is_idle(struct sched_pcore *spc)
-{
-       struct sched_pcore *i;
-       TAILQ_FOREACH(i, &idlecores, alloc_next) {
-               if (spc == i)
-                       return TRUE;
-       }
-       return FALSE;
-}
-
 int get_specific_idle_core(int coreid)
 {
-       struct sched_pcore *spc = pcoreid2spc(coreid);
-       int ret = -1;
-       assert((0 <= coreid) && (coreid < num_cores));
        spin_lock(&sched_lock);
-       if (__spc_is_idle(pcoreid2spc(coreid)) && !spc->prov_proc) {
-               assert(!spc->alloc_proc);
-               TAILQ_REMOVE(&idlecores, spc, alloc_next);
-               ret = coreid;
-       }
+       int ret = __get_specific_idle_core(coreid);
        spin_unlock(&sched_lock);
        return ret;
 }
@@ -559,10 +530,8 @@ int get_specific_idle_core(int coreid)
 /* similar to __sched_put_idle_core, but without the prov tracking */
 void put_idle_core(int coreid)
 {
-       struct sched_pcore *spc = pcoreid2spc(coreid);
-       assert((0 <= coreid) && (coreid < num_cores));
        spin_lock(&sched_lock);
-       TAILQ_INSERT_TAIL(&idlecores, spc, alloc_next);
+       __put_idle_core(coreid);
        spin_unlock(&sched_lock);
 }