M ip/iproute.c => ip/iproute.c +14 -9
@@ 487,8 487,9 @@ v4lookup(Fs *f, uchar *a, Conv *c)
Route *p, *q;
ulong la;
uchar gate[IPaddrlen];
+ Ipifc *ifc;
- if(c != nil && c->r != nil && c->rgen == v4routegeneration)
+ if(c != nil && c->r != nil && c->r->ifc != nil && c->rgen == v4routegeneration)
return c->r;
la = nhgetl(a);
@@ 509,11 510,13 @@ v4lookup(Fs *f, uchar *a, Conv *c)
memmove(gate, v4prefix, IPv4off);
} else
v4tov6(gate, q->v4.gate);
- q->ifc = findipifc(f, gate, q->type);
- if(q->ifc == nil)
+ ifc = findipifc(f, gate, q->type);
+ if(ifc == nil)
return nil;
- q->ifcid = q->ifc->ifcid;
+ q->ifc = ifc;
+ q->ifcid = ifc->ifcid;
}
+
if(c != nil){
c->r = q;
c->rgen = v4routegeneration;
@@ 530,6 533,7 @@ v6lookup(Fs *f, uchar *a, Conv *c)
int h;
ulong x, y;
uchar gate[IPaddrlen];
+ Ipifc *ifc;
if(memcmp(a, v4prefix, IPv4off) == 0){
q = v4lookup(f, a+IPv4off, c);
@@ 537,7 541,7 @@ v6lookup(Fs *f, uchar *a, Conv *c)
return q;
}
- if(c != nil && c->r != nil && c->rgen == v6routegeneration)
+ if(c != nil && c->r != nil && c->r->ifc != nil && c->rgen == v6routegeneration)
return c->r;
for(h = 0; h < IPllen; h++)
@@ 576,12 580,13 @@ next: ;
if(q->type & Rifc) {
for(h = 0; h < IPllen; h++)
hnputl(gate+4*h, q->v6.address[h]);
- q->ifc = findipifc(f, gate, q->type);
+ ifc = findipifc(f, gate, q->type);
} else
- q->ifc = findipifc(f, q->v6.gate, q->type);
- if(q->ifc == nil)
+ ifc = findipifc(f, q->v6.gate, q->type);
+ if(ifc == nil)
return nil;
- q->ifcid = q->ifc->ifcid;
+ q->ifc = ifc;
+ q->ifcid = ifc->ifcid;
}
if(c != nil){
c->r = q;
M port/portdat.h => port/portdat.h +1 -0
@@ 658,6 658,7 @@ struct Proc
ulong basepri; /* base priority level */
uchar fixedpri; /* priority level deson't change */
int quanta; /* quanta left */
+ uchar yield; /* non-zero if the process just did a sleep(0) */
ulong readytime; /* time process came ready */
ulong movetime; /* last time process switched processors */
int preempted; /* true if this process hasn't finished the interrupt
M port/portfns.h => port/portfns.h +1 -0
@@ 366,6 366,7 @@ void xinit(void);
int xmerge(void*, void*);
void* xspanalloc(ulong, int, ulong);
void xsummary(void);
+void yield(void);
Segment* data2txt(Segment*);
Segment* dupseg(Segment**, int, int);
Segment* newseg(int, ulong, ulong);
M port/proc.c => port/proc.c +22 -5
@@ 259,6 259,21 @@ ready(Proc *p)
splx(s);
}
+/*
+ * yield the processor to any other runnable process
+ */
+void
+yield(void)
+{
+ if(anyready()){
+ up->yield = 1;
+ sched();
+ }
+}
+
+/*
+ * pick a process to run
+ */
Proc*
runproc(void)
{
@@ 282,13 297,15 @@ 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){
+ for(tp = rq->head; tp; tp = tp->rnext){
+ if(tp->yield){
+ tp->yield = 0;
+ continue;
+ }
if(tp->mp == nil || tp->mp == MACHP(m->machno)
|| (!tp->wired && i > 0))
goto found;
M port/sysproc.c => port/sysproc.c +1 -2
@@ 540,8 540,7 @@ syssleep(ulong *arg)
n = arg[0];
if(n <= 0) {
- up->priority = 0;
- sched();
+ yield();
return 0;
}
if(n < TK2MS(1))