diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-10-25 19:51:46 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-10-25 19:51:46 +0200 |
commit | 8cdade591ef30137db38598a01393fe1e306ac40 (patch) | |
tree | 3bb9809ce4f3307d265d7ed649c74381a5898968 | |
parent | c7c7e7ee2afcb21f5523d6b66e539befe2b93b01 (diff) | |
download | plan9front-8cdade591ef30137db38598a01393fe1e306ac40.tar.xz |
kernel: dont spawn closeprocs from closechanq
make closeproc() spawn more procs on demand insead of
doing it from closechanq(). this avoids the palloc lock
checks and simplifies the logic.
-rw-r--r-- | sys/src/9/port/chan.c | 92 |
1 files changed, 51 insertions, 41 deletions
diff --git a/sys/src/9/port/chan.c b/sys/src/9/port/chan.c index 266c6f935..a8bd9522a 100644 --- a/sys/src/9/port/chan.c +++ b/sys/src/9/port/chan.c @@ -480,7 +480,7 @@ struct { Chan *head; Chan *tail; ulong nqueued; - ulong nclosed; + ulong nclosed; Lock l; QLock q; Rendez r; @@ -493,39 +493,6 @@ clunkwork(void*) } static void -closeproc(void*) -{ - Chan *c; - - for(;;){ - if(clunkq.head == nil){ - if(!waserror()){ - tsleep(&clunkq.r, clunkwork, nil, 5000); - poperror(); - } - } - qunlock(&clunkq.q); - lock(&clunkq.l); - c = clunkq.head; - if(c == nil){ - unlock(&clunkq.l); - if(canqlock(&clunkq.q)) - continue; - pexit("no work", 1); - } - clunkq.head = c->next; - clunkq.nclosed++; - unlock(&clunkq.l); - if(!waserror()){ - devtab[c->type]->close(c); - poperror(); - } - chanfree(c); - qlock(&clunkq.q); - } -} - -static void closechanq(Chan *c) { lock(&clunkq.l); @@ -537,17 +504,60 @@ closechanq(Chan *c) clunkq.head = c; clunkq.tail = c; unlock(&clunkq.l); + wakeup(&clunkq.r); +} - if(up != 0 && palloc.Lock.p != up && canqlock(&clunkq.q)){ - c = up->dot; - up->dot = up->slash; /* dummy */ +static Chan* +closechandeq(void) +{ + Chan *c; + + lock(&clunkq.l); + c = clunkq.head; + if(c != nil) { + clunkq.head = c->next; + clunkq.nclosed++; + } + unlock(&clunkq.l); + return c; +} + +static void +closeproc(void *) +{ + Chan *c; + + for(;;){ + c = closechandeq(); + if(c == nil) { + qlock(&clunkq.q); + if(!waserror()) { + tsleep(&clunkq.r, clunkwork, nil, 500); + poperror(); + } + c = closechandeq(); + if(c == nil) { + if(clunkq.q.head != nil) { + qunlock(&clunkq.q); + pexit("no work", 1); + } + qunlock(&clunkq.q); + continue; + } + if(clunkq.q.head == nil) { + if(!waserror()) { + kproc("closeproc", closeproc, nil); + poperror(); + } + } + qunlock(&clunkq.q); + } if(!waserror()){ - kproc("closeproc", closeproc, nil); + devtab[c->type]->close(c); poperror(); } - up->dot = c; - }else - wakeup(&clunkq.r); + chanfree(c); + } } void |