summaryrefslogtreecommitdiffstats
path: root/src/libthread/sched.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-02-29 22:10:26 +0000
committerrsc <devnull@localhost>2004-02-29 22:10:26 +0000
commit5a8e63b2f016735364d17866d5e2bcb35d20c78b (patch)
treed5d0ce11e087efaf81c77311bac9d30aed41783d /src/libthread/sched.c
parentd51419bf4397cf13d0c50bf84c125477c6bed307 (diff)
downloadplan9port-5a8e63b2f016735364d17866d5e2bcb35d20c78b.tar.gz
plan9port-5a8e63b2f016735364d17866d5e2bcb35d20c78b.zip
Fighting the good fight.
Move libfmt, libutf into subdirectories of lib9. Add poll-based socket i/o to libthread, so that we can avoid using multiple procs when possible, thus removing dependence on crappy pthreads implementations. Convert samterm, acme to the single-proc libthread. Bring libcomplete, acme up-to-date w.r.t. Plan 9 distribution.
Diffstat (limited to 'src/libthread/sched.c')
-rw-r--r--src/libthread/sched.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libthread/sched.c b/src/libthread/sched.c
index d85a76e2..755fc280 100644
--- a/src/libthread/sched.c
+++ b/src/libthread/sched.c
@@ -1,4 +1,5 @@
#include <signal.h>
+#include <errno.h>
#include "threadimpl.h"
//static Thread *runthread(Proc*);
@@ -67,10 +68,12 @@ _schedinit(void *arg)
t = nil;
_sched();
}
+/*
if(p->needexec){
t->ret = _schedexec(&p->exec);
p->needexec = 0;
}
+*/
if(p->newproc){
t->ret = _schedfork(p->newproc);
if(t->ret < 0){
@@ -90,14 +93,45 @@ _schedinit(void *arg)
static Thread*
runthread(Proc *p)
{
+ Channel *c;
Thread *t;
Tqueue *q;
+ Waitmsg *w;
+ int e, sent;
if(p->nthreads==0 || (p->nthreads==1 && p->idle))
return nil;
q = &p->ready;
+relock:
lock(&p->readylock);
if(q->head == nil){
+ e = errno;
+ if((c = _threadwaitchan) != nil){
+ if(c->n <= c->s){
+ sent = 0;
+ for(;;){
+ if((w = p->waitmsg) != nil)
+ p->waitmsg = nil;
+ else
+ w = waitnohang();
+ if(w == nil)
+ break;
+ if(sent == 0){
+ unlock(&p->readylock);
+ sent = 1;
+ }
+ if(nbsendp(c, w) != 1)
+ break;
+ }
+ p->waitmsg = w;
+ if(sent)
+ goto relock;
+ }
+ }else{
+ while((w = waitnohang()) != nil)
+ free(w);
+ }
+ errno = e;
if(p->idle){
if(p->idle->state != Ready){
fprint(2, "everyone is asleep\n");