diff options
Diffstat (limited to 'src/libthread')
-rw-r--r-- | src/libthread/asm-FreeBSD-386.s | 4 | ||||
-rw-r--r-- | src/libthread/create.c | 8 | ||||
-rw-r--r-- | src/libthread/exec-unix.c | 22 | ||||
-rw-r--r-- | src/libthread/exec.c | 13 | ||||
-rw-r--r-- | src/libthread/main.c | 3 | ||||
-rw-r--r-- | src/libthread/note.c | 4 | ||||
-rw-r--r-- | src/libthread/sched.c | 28 | ||||
-rw-r--r-- | src/libthread/threadimpl.h | 2 |
8 files changed, 56 insertions, 28 deletions
diff --git a/src/libthread/asm-FreeBSD-386.s b/src/libthread/asm-FreeBSD-386.s index 7cad85cc..074556f9 100644 --- a/src/libthread/asm-FreeBSD-386.s +++ b/src/libthread/asm-FreeBSD-386.s @@ -41,9 +41,9 @@ _xdec: movl 4(%esp), %eax lock decl 0(%eax) jz iszero - movl %eax, 1 + movl $1, %eax ret iszero: - movl %eax, 0 + movl $0, %eax ret diff --git a/src/libthread/create.c b/src/libthread/create.c index 55f6c60c..d487e195 100644 --- a/src/libthread/create.c +++ b/src/libthread/create.c @@ -1,8 +1,7 @@ #include "threadimpl.h" Pqueue _threadpq; - -int _threadmultiproc; +int _threadprocs; static int nextID(void); @@ -90,7 +89,6 @@ proccreate(void (*f)(void*), void *arg, uint stacksize) werrstr("cannot create procs once there is an idle thread"); return -1; } - _threadmultiproc = 1; return procrfork(f, arg, stacksize, 0); } @@ -125,11 +123,12 @@ threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize) { int id; - if(_threadmultiproc){ + if(_threadprocs!=1){ werrstr("cannot have idle thread in multi-proc program"); return -1; } id = newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp()); + _threaddebug(DBGSCHED, "idle is %d", id); _threadidle(); return id; } @@ -154,6 +153,7 @@ _newproc(void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp, i else *_threadpq.tail = p; _threadpq.tail = &p->next; + _threadprocs++; unlock(&_threadpq.lock); return p; } diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c index ef50bf19..97c75607 100644 --- a/src/libthread/exec-unix.c +++ b/src/libthread/exec-unix.c @@ -3,7 +3,7 @@ #include "threadimpl.h" void -procexec(Channel *pidc, char *prog, char *args[]) +procexec(Channel *pidc, int fd[3], char *prog, char *args[]) { int n; Proc *p; @@ -45,6 +45,7 @@ procexec(Channel *pidc, char *prog, char *args[]) assert(p->needexec==0); p->exec.prog = prog; p->exec.args = args; + p->exec.stdfd = fd; p->needexec = 1; _sched(); @@ -56,7 +57,11 @@ procexec(Channel *pidc, char *prog, char *args[]) goto Bad; } close(p->exec.fd[0]); - + close(fd[0]); + if(fd[1] != fd[0]) + close(fd[1]); + if(fd[2] != fd[1] && fd[2] != fd[0]) + close(fd[2]); if(pidc) sendul(pidc, t->ret); @@ -66,9 +71,9 @@ procexec(Channel *pidc, char *prog, char *args[]) } void -procexecl(Channel *pidc, char *f, ...) +procexecl(Channel *pidc, int fd[3], char *f, ...) { - procexec(pidc, f, &f+1); + procexec(pidc, fd, f, &f+1); } void @@ -107,10 +112,17 @@ efork(void *ve) { char buf[ERRMAX]; Execargs *e; + int i; e = ve; _threaddebug(DBGEXEC, "_schedexec %s -- calling execv", e->prog); - execv(e->prog, e->args); + dup(e->stdfd[0], 0); + dup(e->stdfd[1], 1); + dup(e->stdfd[2], 2); + for(i=3; i<40; i++) + if(i != e->fd[1]) + close(i); + execvp(e->prog, e->args); _threaddebug(DBGEXEC, "_schedexec failed: %r"); rerrstr(buf, sizeof buf); if(buf[0]=='\0') diff --git a/src/libthread/exec.c b/src/libthread/exec.c index bcf20802..0fb68111 100644 --- a/src/libthread/exec.c +++ b/src/libthread/exec.c @@ -3,7 +3,7 @@ #define PIPEMNT "/mnt/temp" void -procexec(Channel *pidc, char *prog, char *args[]) +procexec(Channel *pidc, int fd[3], char *prog, char *args[]) { int n; Proc *p; @@ -50,6 +50,7 @@ procexec(Channel *pidc, char *prog, char *args[]) assert(p->needexec==0); p->exec.prog = prog; p->exec.args = args; + p->exec.stdfd = fd; p->needexec = 1; _sched(); @@ -61,7 +62,11 @@ procexec(Channel *pidc, char *prog, char *args[]) goto Bad; } close(p->exec.fd[0]); - + close(fd[0]); + if(fd[1] != fd[0]) + close(fd[1]); + if(fd[2] != fd[1] && fd[2] != fd[0]) + close(fd[2]); if(pidc) sendul(pidc, t->ret); @@ -70,8 +75,8 @@ procexec(Channel *pidc, char *prog, char *args[]) } void -procexecl(Channel *pidc, char *f, ...) +procexecl(Channel *pidc, int fd[3], char *f, ...) { - procexec(pidc, f, &f+1); + procexec(pidc, fd, f, &f+1); } diff --git a/src/libthread/main.c b/src/libthread/main.c index 06c12935..97a6154a 100644 --- a/src/libthread/main.c +++ b/src/libthread/main.c @@ -37,7 +37,7 @@ main(int argc, char **argv) _systhreadinit(); _qlockinit(_threadrendezvous); _sysfatal = _threadsysfatal; -// notify(_threadnote); + notify(_threadnote); if(mainstacksize == 0) mainstacksize = 32*1024; @@ -98,6 +98,7 @@ _schedexit(Proc *p) break; } } + _threadprocs--; unlock(&_threadpq.lock); strncpy(ex, p->exitstr, sizeof ex); diff --git a/src/libthread/note.c b/src/libthread/note.c index b7f4b137..b25f2b23 100644 --- a/src/libthread/note.c +++ b/src/libthread/note.c @@ -2,7 +2,6 @@ int _threadnopasser; -#ifdef NOTDEF #define NFN 33 #define ERRLEN 48 typedef struct Note Note; @@ -85,7 +84,7 @@ _threadnote(void *v, char *s) Note *n; _threaddebug(DBGNOTE, "Got note %s", s); - if(strncmp(s, "sys:", 4) == 0) + if(strncmp(s, "sys:", 4) == 0 && strcmp(s, "sys: write on closed pipe") != 0) noted(NDFLT); // if(_threadexitsallstatus){ @@ -112,7 +111,6 @@ _threadnote(void *v, char *s) delayednotes(p, v); noted(NCONT); } -#endif int _procsplhi(void) diff --git a/src/libthread/sched.c b/src/libthread/sched.c index d6af1c7c..d85a76e2 100644 --- a/src/libthread/sched.c +++ b/src/libthread/sched.c @@ -98,17 +98,18 @@ runthread(Proc *p) 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); + _threaddebug(DBGSCHED, "running idle thread", p->nthreads); return p->idle; } _threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads); + q->asleep = 1; unlock(&p->readylock); while(rendezvous((ulong)q, 0) == ~0){ if(_threadexitsallstatus) @@ -148,7 +149,7 @@ Resched: _threaddelproc(); _schedexit(p); } - // _threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id); + _threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id); p->thread = t; if(t->moribund){ _threaddebug(DBGSCHED, "%d.%d marked to die"); @@ -176,8 +177,10 @@ _threadready(Thread *t) { Tqueue *q; - if(t == t->proc->idle) + if(t == t->proc->idle){ + _threaddebug(DBGSCHED, "idle thread is ready"); return; + } assert(t->state == Ready); _threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id); @@ -206,18 +209,25 @@ void _threadidle(void) { Tqueue *q; - Thread *t; + Thread *t, *idle; Proc *p; p = _threadgetproc(); q = &p->ready; lock(&p->readylock); - assert(q->head); - t = q->head; - q->head = t->next; - if(q->tail == t) + assert(q->tail); + idle = q->tail; + if(q->head == idle){ + q->head = nil; q->tail = nil; - p->idle = t; + }else{ + for(t=q->head; t->next!=q->tail; t=t->next) + ; + t->next = nil; + q->tail = t; + } + p->idle = idle; + _threaddebug(DBGSCHED, "p->idle is %d\n", idle->id); unlock(&p->readylock); } diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index aa69845c..0dd1e870 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -105,6 +105,7 @@ struct Execargs char *prog; char **args; int fd[2]; + int *stdfd; }; struct Proc @@ -214,4 +215,5 @@ extern void _stackfree(void*); extern int _threadgetpid(void); extern void _threadmemset(void*, int, int); extern void _threaddebugmemset(void*, int, int); +extern int _threadprocs; |