|
@@ -259,11 +259,101 @@ ready(Proc *p)
|
|
|
splx(s);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * remove a process from a scheduling queue (called splhi)
|
|
|
+ */
|
|
|
+static Proc*
|
|
|
+dequeueproc(Schedq *rq, Proc *tp)
|
|
|
+{
|
|
|
+ Proc *l, *p;
|
|
|
+
|
|
|
+ if(!canlock(runq))
|
|
|
+ return nil;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * the queue may have changed before we locked runq,
|
|
|
+ * refind the target process.
|
|
|
+ */
|
|
|
+ l = 0;
|
|
|
+ for(p = rq->head; p; p = p->rnext){
|
|
|
+ if(p == tp)
|
|
|
+ break;
|
|
|
+ l = p;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * p->mach==0 only when process state is saved
|
|
|
+ */
|
|
|
+ if(p == 0 || p->mach){
|
|
|
+ unlock(runq);
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+ if(p->rnext == 0)
|
|
|
+ rq->tail = l;
|
|
|
+ if(l)
|
|
|
+ l->rnext = p->rnext;
|
|
|
+ else
|
|
|
+ rq->head = p->rnext;
|
|
|
+ if(rq->head == nil)
|
|
|
+ runvec &= ~(1<<(rq-runq));
|
|
|
+ rq->n--;
|
|
|
+ nrdy--;
|
|
|
+ if(p->state != Ready)
|
|
|
+ print("dequeueproc %s %lud %s\n", p->text, p->pid, statename[p->state]);
|
|
|
+
|
|
|
+ unlock(runq);
|
|
|
+ return p;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * yield the processor and drop our priority
|
|
|
+ */
|
|
|
+void
|
|
|
+yield(void)
|
|
|
+{
|
|
|
+ if(anyready()){
|
|
|
+ up->quanta = 0; /* act like you used them all up */
|
|
|
+ sched();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * move up any process waiting more than its quanta
|
|
|
+ */
|
|
|
+static void
|
|
|
+rebalance(void)
|
|
|
+{
|
|
|
+ Schedq *rq;
|
|
|
+ Proc *p;
|
|
|
+
|
|
|
+ for(rq = runq; rq < &runq[Nrq]; rq++){
|
|
|
+ p = rq->head;
|
|
|
+ if(p == nil)
|
|
|
+ continue;
|
|
|
+ if(p->mp != MACHP(m->machno))
|
|
|
+ continue;
|
|
|
+ if(p->priority == p->basepri)
|
|
|
+ continue;
|
|
|
+ if(m->ticks - p->readytime < quanta[p->priority]/4)
|
|
|
+ continue;
|
|
|
+ splhi();
|
|
|
+ p = dequeueproc(rq, p);
|
|
|
+ spllo();
|
|
|
+ if(p == nil)
|
|
|
+ continue;
|
|
|
+ p->quanta = quanta[p->priority]; /* act like we used none */
|
|
|
+ ready(p);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * pick a process to run
|
|
|
+ */
|
|
|
Proc*
|
|
|
runproc(void)
|
|
|
{
|
|
|
Schedq *rq;
|
|
|
- Proc *p, *l, *tp;
|
|
|
+ Proc *p;
|
|
|
ulong start, now;
|
|
|
int i;
|
|
|
|
|
@@ -272,6 +362,11 @@ runproc(void)
|
|
|
if ((p = edf->edfrunproc()) != nil)
|
|
|
return p;
|
|
|
|
|
|
+ if(m->fairness++ == 10){
|
|
|
+ m->fairness = 0;
|
|
|
+ rebalance();
|
|
|
+ }
|
|
|
+
|
|
|
loop:
|
|
|
/*
|
|
|
* find a process that last ran on this processor (affinity),
|
|
@@ -282,15 +377,13 @@ loop:
|
|
|
for(i = 0;; i++){
|
|
|
/*
|
|
|
* find the highest priority target process that this
|
|
|
- * processor can run given affinity constraints
|
|
|
+ * processor can run given affinity constraints.
|
|
|
+ *
|
|
|
*/
|
|
|
for(rq = &runq[Nrq-1]; rq >= runq; rq--){
|
|
|
- tp = rq->head;
|
|
|
- if(tp == 0)
|
|
|
- continue;
|
|
|
- for(; tp; tp = tp->rnext){
|
|
|
- if(tp->mp == nil || tp->mp == MACHP(m->machno)
|
|
|
- || (!tp->wired && i > 0))
|
|
|
+ for(p = rq->head; p; p = p->rnext){
|
|
|
+ if(p->mp == nil || p->mp == MACHP(m->machno)
|
|
|
+ || (!p->wired && i > 0))
|
|
|
goto found;
|
|
|
}
|
|
|
}
|
|
@@ -306,41 +399,10 @@ loop:
|
|
|
|
|
|
found:
|
|
|
splhi();
|
|
|
- if(!canlock(runq))
|
|
|
+ p = dequeueproc(rq, p);
|
|
|
+ if(p == nil)
|
|
|
goto loop;
|
|
|
|
|
|
- /*
|
|
|
- * the queue may have changed before we locked runq,
|
|
|
- * refind the target process.
|
|
|
- */
|
|
|
- l = 0;
|
|
|
- for(p = rq->head; p; p = p->rnext){
|
|
|
- if(p == tp)
|
|
|
- break;
|
|
|
- l = p;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * p->mach==0 only when process state is saved
|
|
|
- */
|
|
|
- if(p == 0 || p->mach){
|
|
|
- unlock(runq);
|
|
|
- goto loop;
|
|
|
- }
|
|
|
- if(p->rnext == 0)
|
|
|
- rq->tail = l;
|
|
|
- if(l)
|
|
|
- l->rnext = p->rnext;
|
|
|
- else
|
|
|
- rq->head = p->rnext;
|
|
|
- if(rq->head == nil)
|
|
|
- runvec &= ~(1<<(rq-runq));
|
|
|
- rq->n--;
|
|
|
- nrdy--;
|
|
|
- if(p->state != Ready)
|
|
|
- print("runproc %s %lud %s\n", p->text, p->pid, statename[p->state]);
|
|
|
- unlock(runq);
|
|
|
-
|
|
|
p->state = Scheding;
|
|
|
p->mp = MACHP(m->machno);
|
|
|
|