Add support for user-level 9P servers/clients and various bug fixes to go with them.

This commit is contained in:
rsc 2003-12-11 17:48:38 +00:00
parent ac244f8d28
commit 32f69c36e0
60 changed files with 965 additions and 485 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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')

View file

@ -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);
}

View file

@ -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);

View file

@ -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)

View file

@ -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);
}

View file

@ -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;