diff options
-rw-r--r-- | include/fcall.h | 8 | ||||
-rw-r--r-- | include/thread.h | 1 | ||||
-rw-r--r-- | src/cmd/9term/9term.c | 3 | ||||
-rw-r--r-- | src/cmd/dict/dict.c | 1 | ||||
-rw-r--r-- | src/cmd/mkfile | 2 | ||||
-rw-r--r-- | src/lib9/mkfile | 5 | ||||
-rw-r--r-- | src/libthread/create.c | 24 | ||||
-rw-r--r-- | src/libthread/exit.c | 2 | ||||
-rw-r--r-- | src/libthread/sched.c | 33 | ||||
-rw-r--r-- | src/libthread/threadimpl.h | 3 |
10 files changed, 74 insertions, 8 deletions
diff --git a/include/fcall.h b/include/fcall.h index 20ffe386..f85487bd 100644 --- a/include/fcall.h +++ b/include/fcall.h @@ -1,7 +1,7 @@ #ifndef _FCALL_H_ #define _FCALL_H_ 1 -#if defined(__cplusplus) -extern "C" { +#ifdef __cplusplus +extern "C" { #endif /* #pragma src "/sys/src/libc/9sys" @@ -9,7 +9,6 @@ extern "C" { */ #define VERSION9P "9P2000" - #define MAXWELEM 16 typedef @@ -123,7 +122,8 @@ int read9pmsg(int, void*, uint); #pragma varargck type "M" ulong #pragma varargck type "D" Dir* */ -#if defined(__cplusplus) + +#ifdef __cplusplus } #endif #endif diff --git a/include/thread.h b/include/thread.h index 9c5d2d09..e9dc96e0 100644 --- a/include/thread.h +++ b/include/thread.h @@ -88,6 +88,7 @@ int send(Channel *c, void *v); int sendp(Channel *c, void *v); int sendul(Channel *c, unsigned long v); int threadcreate(void (*f)(void *arg), void *arg, unsigned int stacksize); +int threadcreateidle(void (*f)(void*), void*, unsigned int); void** threaddata(void); void threadexits(char *); void threadexitsall(char *); diff --git a/src/cmd/9term/9term.c b/src/cmd/9term/9term.c index 1b65b88c..ef51d864 100644 --- a/src/cmd/9term/9term.c +++ b/src/cmd/9term/9term.c @@ -318,7 +318,8 @@ aselect(uint *q0, uint *q1, Image *color) } /* clicked inside previous selection */ - if(oldq0 <= newq0 && newq0 < oldq1){ + /* the "<=" in newq0 <= oldq1 allows us to click the right edge */ + if(oldq0 <= newq0 && newq0 <= oldq1){ *q0 = oldq0; *q1 = oldq1; return 0; diff --git a/src/cmd/dict/dict.c b/src/cmd/dict/dict.c index 00534ea0..dccd3037 100644 --- a/src/cmd/dict/dict.c +++ b/src/cmd/dict/dict.c @@ -230,7 +230,6 @@ execcmd(int cmd) if(debug && doall && cmd == 'a') Bprint(bout, "%d entries, cur=%d\n", dot->n, cur+1); for(;;){ -print("execcmd dot->n %d\n", dot->n); if(cur >= dot->n) break; if(doall) { diff --git a/src/cmd/mkfile b/src/cmd/mkfile index b8a63c57..8450d94b 100644 --- a/src/cmd/mkfile +++ b/src/cmd/mkfile @@ -2,7 +2,7 @@ PLAN9=../.. <$PLAN9/src/mkhdr TARG=`ls *.c | sed 's/\.c//'` -LDFLAGS=$LDFLAGS -lsec -lregexp9 -l9 -lbio -lfmt -lutf +LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -l9 -lbio -lfmt -lutf <$PLAN9/src/mkmany diff --git a/src/lib9/mkfile b/src/lib9/mkfile index 3dbd6b4a..14d8c0e0 100644 --- a/src/lib9/mkfile +++ b/src/lib9/mkfile @@ -17,6 +17,10 @@ OFILES=\ cistrncmp.$O\ cistrstr.$O\ cleanname.$O\ + convD2M.$O\ + convM2D.$O\ + convM2S.$O\ + convS2M.$O\ create.$O\ ctime.$O\ date.$O\ @@ -31,6 +35,7 @@ OFILES=\ encodefmt.$O\ errstr.$O\ exec.$O\ + fcallfmt.$O\ ffork-$SYSNAME.$O\ getcallerpc-$OBJTYPE.$O\ getenv.$O\ diff --git a/src/libthread/create.c b/src/libthread/create.c index 6a44c243..55f6c60c 100644 --- a/src/libthread/create.c +++ b/src/libthread/create.c @@ -2,6 +2,8 @@ Pqueue _threadpq; +int _threadmultiproc; + static int nextID(void); /* @@ -81,6 +83,14 @@ procrfork(void (*f)(void *), void *arg, uint stacksize, int rforkflag) int proccreate(void (*f)(void*), void *arg, uint stacksize) { + Proc *p; + + p = _threadgetproc(); + if(p->idle){ + werrstr("cannot create procs once there is an idle thread"); + return -1; + } + _threadmultiproc = 1; return procrfork(f, arg, stacksize, 0); } @@ -110,6 +120,20 @@ threadcreate(void (*f)(void *arg), void *arg, uint stacksize) return newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp()); } +int +threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize) +{ + int id; + + if(_threadmultiproc){ + werrstr("cannot have idle thread in multi-proc program"); + return -1; + } + id = newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp()); + _threadidle(); + return id; +} + /* * Create and initialize a new Proc structure with a single Thread * running inside it. Add the Proc to the global process list. diff --git a/src/libthread/exit.c b/src/libthread/exit.c index 511e5bca..4cda307e 100644 --- a/src/libthread/exit.c +++ b/src/libthread/exit.c @@ -12,6 +12,8 @@ threadexits(char *exitstr) p = _threadgetproc(); t = p->thread; + if(t == p->idle) + p->idle = nil; t->moribund = 1; _threaddebug(DBGSCHED, "threadexits %s", exitstr); if(exitstr==nil) diff --git a/src/libthread/sched.c b/src/libthread/sched.c index 293e3306..d6af1c7c 100644 --- a/src/libthread/sched.c +++ b/src/libthread/sched.c @@ -93,12 +93,21 @@ runthread(Proc *p) Thread *t; Tqueue *q; - if(p->nthreads==0) + if(p->nthreads==0 || (p->nthreads==1 && p->idle)) return nil; q = &p->ready; lock(&p->readylock); if(q->head == nil){ q->asleep = 1; + if(p->idle){ + if(p->idle->state != Ready){ + fprint(2, "everyone is asleep\n"); + exits("everyone is asleep"); + } + unlock(&p->readylock); + return p->idle; + } + _threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads); unlock(&p->readylock); while(rendezvous((ulong)q, 0) == ~0){ @@ -167,6 +176,9 @@ _threadready(Thread *t) { Tqueue *q; + if(t == t->proc->idle) + return; + assert(t->state == Ready); _threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id); q = &t->proc->ready; @@ -191,6 +203,25 @@ _threadready(Thread *t) } void +_threadidle(void) +{ + Tqueue *q; + Thread *t; + Proc *p; + + p = _threadgetproc(); + q = &p->ready; + lock(&p->readylock); + assert(q->head); + t = q->head; + q->head = t->next; + if(q->tail == t) + q->tail = nil; + p->idle = t; + unlock(&p->readylock); +} + +void yield(void) { _sched(); diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index d9b22403..aa69845c 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -115,6 +115,7 @@ struct Proc int pid; /* process id */ int splhi; /* delay notes */ Thread *thread; /* running thread */ + Thread *idle; /* idle thread */ int needexec; Execargs exec; /* exec argument */ @@ -185,6 +186,7 @@ void _threadinitstack(Thread*, void(*)(void*), void*); void* _threadmalloc(long, int); void _threadnote(void*, char*); void _threadready(Thread*); +void _threadidle(void); ulong _threadrendezvous(ulong, ulong); void _threadsignal(void); void _threadsysfatal(char*, va_list); @@ -192,6 +194,7 @@ long _xdec(long*); void _xinc(long*); void _threadremove(Proc*, Thread*); +extern int _threadmultiproc; extern int _threaddebuglevel; extern char* _threadexitsallstatus; extern Pqueue _threadpq; |