aboutsummaryrefslogtreecommitdiff
path: root/src/libthread
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-12-11 17:48:38 +0000
committerrsc <devnull@localhost>2003-12-11 17:48:38 +0000
commit32f69c36e0eec1227934bbd34854bfebd88686f2 (patch)
tree1587e9de84816b77168afa81c1594cc686809910 /src/libthread
parentac244f8d287a6119155ea672c8fd13c487c5e4c7 (diff)
downloadplan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.tar.gz
plan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.tar.bz2
plan9port-32f69c36e0eec1227934bbd34854bfebd88686f2.zip
Add support for user-level 9P servers/clients and various bug fixes to go with them.
Diffstat (limited to 'src/libthread')
-rw-r--r--src/libthread/asm-FreeBSD-386.s4
-rw-r--r--src/libthread/create.c8
-rw-r--r--src/libthread/exec-unix.c22
-rw-r--r--src/libthread/exec.c13
-rw-r--r--src/libthread/main.c3
-rw-r--r--src/libthread/note.c4
-rw-r--r--src/libthread/sched.c28
-rw-r--r--src/libthread/threadimpl.h2
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;