commit e97ceade5e1bba5787e39429384336fa37797906 from: rsc date: Sat Dec 06 18:05:27 2003 UTC various tweaks. commit - c715a6127a46b8090591972b5c4bb04dfabbca8b commit + e97ceade5e1bba5787e39429384336fa37797906 blob - 20ffe3861d9174d0d3c00dbcb9ce9311e92e998e blob + f85487bd7af777d557aab3eaa0a53cb73dbe237d --- include/fcall.h +++ 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 blob - 9c5d2d0925978dc58da2b480dc6ffd3779ad7875 blob + e9dc96e031bc83452a1ba63890272997a0a4a26f --- include/thread.h +++ 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 *); blob - 1b65b88c13f193099276b0d0494e91336ceaaa95 blob + ef51d864b35a4acabeaf6aeb2ecc7ffe8f184d2c --- src/cmd/9term/9term.c +++ 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; blob - 00534ea0afe4eb8856f3bb278149f2816eb64855 blob + dccd3037022755943512cee76eadb33c3947a592 --- src/cmd/dict/dict.c +++ 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) { blob - b8a63c5714c8f854c690acba69126db45aea059b blob + 8450d94bf5833cd02b3a0b0c36ba7c9494d503f7 --- src/cmd/mkfile +++ 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 blob - 3dbd6b4a731d4c2919d802b908b79aa9f306f73c blob + 14d8c0e080846b16b1a2c6870df2eec872cfb99d --- src/lib9/mkfile +++ 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\ blob - 6a44c2437647054f0f81b504cd869b2e28aa5380 blob + 55f6c60cfb1ae78885bd52ace003667003cdfea8 --- src/libthread/create.c +++ 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 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 sta 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. blob - 511e5bcaf9dbd746ccf05356f2cf07953ae9da91 blob + 4cda307e1b0331afe942bf93735a9f718e78192f --- src/libthread/exit.c +++ 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) blob - 293e330626d6eb6fdb0d8636a94a72cef04e30b3 blob + d6af1c7c0a9977e243f2fad904acaeaa751648ed --- src/libthread/sched.c +++ 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(); blob - d9b22403225d987151c09bdf0f71bb099683270d blob + aa69845cda2fc43adc2afa964b6be25538b9e2f6 --- src/libthread/threadimpl.h +++ 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;