make -> mk

remove clumsy stack hack.
fix exec.
fix nthreads maintenance.
fix threadexitsall not to kill self.
add sun support.
This commit is contained in:
rsc 2003-11-23 18:18:00 +00:00
parent b7e6f4150f
commit cd7ddc9b5f
10 changed files with 105 additions and 116 deletions

View file

@ -1,52 +0,0 @@
PLAN9=../..
include $(PLAN9)/src/Makehdr
LIB=libthread.a
OFILES=\
$(OBJTYPE).$O\
asm-$(SYSNAME)-$(OBJTYPE).$O\
channel.$O\
chanprint.$O\
create.$O\
debug.$O\
exec-unix.$O\
exit.$O\
getpid.$O\
id.$O\
iocall.$O\
ioclose.$O\
ioopen.$O\
ioproc.$O\
ioread.$O\
ioreadn.$O\
iowrite.$O\
kill.$O\
lib.$O\
main.$O\
memset.$O\
memsetd.$O\
note.$O\
proctab.$O\
ref.$O\
rendez.$O\
sched.$O\
HFILES=\
$(PLAN9)/include/thread.h\
label.h\
threadimpl.h\
include $(PLAN9)/src/Makesyslib
tprimes: tprimes.$O $(PLAN9)/lib/$(LIB)
$(LD) -o tprimes tprimes.$O $(LDFLAGS) -lthread -l9 -lfmt -lutf
texec: texec.$O $(PLAN9)/lib/$(LIB)
$(LD) -o texec texec.$O $(LDFLAGS) -lthread -l9 -lfmt -lutf
trend: trend.$O $(PLAN9)/lib/$(LIB)
$(LD) -o trend trend.$O $(LDFLAGS) -lthread -l9 -lfmt -lutf
CLEANFILES+=tprimes texec

View file

@ -7,54 +7,10 @@ static int nextID(void);
/* /*
* Create and initialize a new Thread structure attached to a given proc. * Create and initialize a new Thread structure attached to a given proc.
*/ */
typedef struct Stack Stack;
struct Stack {
ulong magic;
Thread *thr;
Stack *next;
uchar buf[STKSIZE-12];
};
static Stack *stkfree;
static Lock stklock;
void void
_stackfree(void *v) _stackfree(void *v)
{ {
Stack *s; free(v);
s = v;
lock(&stklock);
s->thr = nil;
s->magic = 0;
s->next = stkfree;
stkfree = s;
unlock(&stklock);
}
static Stack*
stackalloc(void)
{
char *buf;
Stack *s;
int i;
lock(&stklock);
while(stkfree == nil){
unlock(&stklock);
assert(STKSIZE == sizeof(Stack));
buf = malloc(STKSIZE+128*STKSIZE);
s = (Stack*)(((ulong)buf+STKSIZE)&~(STKSIZE-1));
for(i=0; i<128; i++)
_stackfree(&s[i]);
lock(&stklock);
}
s = stkfree;
stkfree = stkfree->next;
unlock(&stklock);
s->magic = STKMAGIC;
return s;
} }
static int static int
@ -62,16 +18,15 @@ newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize, char *name,
{ {
int id; int id;
Thread *t; Thread *t;
Stack *s; char *s;
if(stacksize < 32) if(stacksize < 32)
sysfatal("bad stacksize %d", stacksize); sysfatal("bad stacksize %d", stacksize);
t = _threadmalloc(sizeof(Thread), 1); t = _threadmalloc(sizeof(Thread), 1);
s = stackalloc(); s = _threadmalloc(stacksize, 0);
s->thr = t;
t->stk = (char*)s; t->stk = (char*)s;
t->stksize = STKSIZE; t->stksize = stacksize;
_threaddebugmemset(s->buf, 0xFE, sizeof s->buf); _threaddebugmemset(s, 0xFE, stacksize);
_threadinitstack(t, f, arg); _threadinitstack(t, f, arg);
t->proc = p; t->proc = p;
t->grp = grp; t->grp = grp;
@ -138,7 +93,7 @@ _freeproc(Proc *p)
if(t->cmdname) if(t->cmdname)
free(t->cmdname); free(t->cmdname);
assert(t->stk != nil); assert(t->stk != nil);
_stackfree((Stack*)t->stk); _stackfree(t->stk);
nextt = t->nextt; nextt = t->nextt;
free(t); free(t);
} }

View file

@ -9,11 +9,13 @@ procexec(Channel *pidc, char *prog, char *args[])
Proc *p; Proc *p;
Thread *t; Thread *t;
print("procexec\n");
_threaddebug(DBGEXEC, "procexec %s", prog); _threaddebug(DBGEXEC, "procexec %s", prog);
/* must be only thread in proc */ /* must be only thread in proc */
p = _threadgetproc(); p = _threadgetproc();
t = p->thread; t = p->thread;
if(p->threads.head != t || p->threads.head->nextt != nil){ if(p->threads.head != t || p->threads.head->nextt != nil){
print("not only thread\n");
werrstr("not only thread in proc"); werrstr("not only thread in proc");
Bad: Bad:
if(pidc) if(pidc)
@ -34,26 +36,35 @@ procexec(Channel *pidc, char *prog, char *args[])
* pipe to us. * pipe to us.
*/ */
if(pipe(p->exec.fd) < 0) if(pipe(p->exec.fd) < 0)
{
print("pipe\n");
goto Bad; goto Bad;
}
if(fcntl(p->exec.fd[1], F_SETFD, 1) < 0) if(fcntl(p->exec.fd[1], F_SETFD, 1) < 0)
{
print("fcntl\n");
goto Bad; goto Bad;
}
/* exec in parallel via the scheduler */ /* exec in parallel via the scheduler */
assert(p->needexec==0); assert(p->needexec==0);
p->exec.prog = prog; p->exec.prog = prog;
p->exec.args = args; p->exec.args = args;
p->needexec = 1; p->needexec = 1;
print("sched\n");
_sched(); _sched();
close(p->exec.fd[1]); close(p->exec.fd[1]);
if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){ /* exec failed */ if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){ /* exec failed */
p->exitstr[n] = '\0'; p->exitstr[n] = '\0';
print("read got %s\n", p->exitstr);
errstr(p->exitstr, ERRMAX); errstr(p->exitstr, ERRMAX);
close(p->exec.fd[0]); close(p->exec.fd[0]);
goto Bad; goto Bad;
} }
close(p->exec.fd[0]); close(p->exec.fd[0]);
print("exec %d\n", pidc);
if(pidc) if(pidc)
sendul(pidc, t->ret); sendul(pidc, t->ret);

View file

@ -1,5 +1,5 @@
#include "threadimpl.h"
#include <signal.h> #include <signal.h>
#include "threadimpl.h"
char *_threadexitsallstatus; char *_threadexitsallstatus;
Channel *_threadwaitchan; Channel *_threadwaitchan;
@ -13,6 +13,7 @@ threadexits(char *exitstr)
p = _threadgetproc(); p = _threadgetproc();
t = p->thread; t = p->thread;
t->moribund = 1; t->moribund = 1;
_threaddebug(DBGSCHED, "threadexits %s", exitstr);
if(exitstr==nil) if(exitstr==nil)
exitstr=""; exitstr="";
utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr); utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr);
@ -26,6 +27,7 @@ threadexitsall(char *exitstr)
int *pid; int *pid;
int i, npid, mypid; int i, npid, mypid;
_threaddebug(DBGSCHED, "threadexitsall %s", exitstr);
if(exitstr == nil) if(exitstr == nil)
exitstr = ""; exitstr = "";
_threadexitsallstatus = exitstr; _threadexitsallstatus = exitstr;
@ -34,7 +36,7 @@ threadexitsall(char *exitstr)
/* /*
* signal others. * signal others.
* copying all the pids first avoids other threads * copying all the pids first avoids other thread's
* teardown procedures getting in the way. * teardown procedures getting in the way.
*/ */
lock(&_threadpq.lock); lock(&_threadpq.lock);
@ -46,9 +48,13 @@ threadexitsall(char *exitstr)
for(p = _threadpq.head; p; p=p->next) for(p = _threadpq.head; p; p=p->next)
pid[npid++] = p->pid; pid[npid++] = p->pid;
unlock(&_threadpq.lock); unlock(&_threadpq.lock);
for(i=0; i<npid; i++) for(i=0; i<npid; i++){
if(pid[i] != mypid) _threaddebug(DBGSCHED, "threadexitsall kill %d", pid[i]);
if(pid[i]==0 || pid[i]==-1)
fprint(2, "bad pid in threadexitsall: %d\n", pid[i]);
else if(pid[i] != mypid)
kill(pid[i], SIGTERM); kill(pid[i], SIGTERM);
}
/* leave */ /* leave */
exit(0); exit(0);

View file

@ -1,5 +1,5 @@
#include "threadimpl.h"
#include <signal.h> #include <signal.h>
#include "threadimpl.h"
static void tinterrupt(Proc*, Thread*); static void tinterrupt(Proc*, Thread*);

View file

@ -32,6 +32,14 @@ struct Label
// uvlong fpr[18]; /* callee saved: f14-f31 */ // uvlong fpr[18]; /* callee saved: f14-f31 */
// ulong vr[4*12]; /* callee saved: v20-v31, 256-bits each */ // ulong vr[4*12]; /* callee saved: v20-v31, 256-bits each */
}; };
#elif defined(__sun__)
struct Label
{
ulong input[8]; /* %i registers */
ulong local[8]; /* %l registers */
ulong sp; /* %o6 */
ulong link; /* %o7 */
};
#else #else
#error "Unknown or unsupported architecture" #error "Unknown or unsupported architecture"
#endif #endif

View file

@ -1,5 +1,5 @@
#include "threadimpl.h"
#include <signal.h> #include <signal.h>
#include "threadimpl.h"
typedef struct Mainarg Mainarg; typedef struct Mainarg Mainarg;
struct Mainarg struct Mainarg
@ -74,7 +74,13 @@ _threadsignalpasser(void)
int int
_schedfork(Proc *p) _schedfork(Proc *p)
{ {
return ffork(RFMEM|RFNOWAIT, _schedinit, p); int pid;
lock(&p->lock);
pid = ffork(RFMEM|RFNOWAIT, _schedinit, p);
p->pid = pid;
unlock(&p->lock);
return pid;
} }
void void

52
src/libthread/mkfile Normal file
View file

@ -0,0 +1,52 @@
PLAN9=../..
<$PLAN9/src/mkhdr
LIB=libthread.a
OFILES=\
$OBJTYPE.$O\
asm-$SYSNAME-$OBJTYPE.$O\
channel.$O\
chanprint.$O\
create.$O\
debug.$O\
exec-unix.$O\
exit.$O\
getpid.$O\
id.$O\
iocall.$O\
ioclose.$O\
ioopen.$O\
ioproc.$O\
ioread.$O\
ioreadn.$O\
iowrite.$O\
kill.$O\
lib.$O\
main.$O\
memset.$O\
memsetd.$O\
note.$O\
proctab.$O\
ref.$O\
rendez.$O\
sched.$O\
HFILES=\
$PLAN9/include/thread.h\
label.h\
threadimpl.h\
<$PLAN9/src/mksyslib
tprimes: tprimes.$O $PLAN9/lib/$LIB
$LD -o tprimes tprimes.$O $LDFLAGS -lthread -l9 -lfmt -lutf
texec: texec.$O $PLAN9/lib/$LIB
$LD -o texec texec.$O $LDFLAGS -lthread -l9 -lfmt -lutf
trend: trend.$O $PLAN9/lib/$LIB
$LD -o trend trend.$O $LDFLAGS -lthread -l9 -lfmt -lutf
CLEANFILES=$CLEANFILES tprimes texec

View file

@ -1,5 +1,5 @@
#include "threadimpl.h"
#include <signal.h> #include <signal.h>
#include "threadimpl.h"
//static Thread *runthread(Proc*); //static Thread *runthread(Proc*);
@ -27,11 +27,11 @@ _schedinit(void *arg)
ignusr1(); ignusr1();
signal(SIGTERM, _threaddie); signal(SIGTERM, _threaddie);
p = arg; p = arg;
lock(&p->lock);
p->pid = _threadgetpid(); p->pid = _threadgetpid();
_threadsetproc(p); _threadsetproc(p);
unlock(&p->lock);
while(_setlabel(&p->sched)) while(_setlabel(&p->sched))
; ;
_threaddebug(DBGSCHED, "top of schedinit, _threadexitsallstatus=%p", _threadexitsallstatus); _threaddebug(DBGSCHED, "top of schedinit, _threadexitsallstatus=%p", _threadexitsallstatus);
@ -59,6 +59,7 @@ _schedinit(void *arg)
_stackfree(t->stk); _stackfree(t->stk);
free(t->cmdname); free(t->cmdname);
free(t); /* XXX how do we know there are no references? */ free(t); /* XXX how do we know there are no references? */
p->nthreads--;
t = nil; t = nil;
_sched(); _sched();
} }
@ -94,7 +95,7 @@ runthread(Proc *p)
lock(&p->readylock); lock(&p->readylock);
if(q->head == nil){ if(q->head == nil){
q->asleep = 1; q->asleep = 1;
_threaddebug(DBGSCHED, "sleeping for more work"); _threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads);
unlock(&p->readylock); unlock(&p->readylock);
while(rendezvous((ulong)q, 0) == ~0){ while(rendezvous((ulong)q, 0) == ~0){
if(_threadexitsallstatus) if(_threadexitsallstatus)
@ -173,6 +174,7 @@ _threadready(Thread *t)
q->tail->next = t; q->tail->next = t;
q->tail = t; q->tail = t;
if(q->asleep){ if(q->asleep){
assert(q->asleep == 1);
q->asleep = 0; q->asleep = 0;
/* lock passes to runthread */ /* lock passes to runthread */
_threaddebug(DBGSCHED, "waking process %d", t->proc->pid); _threaddebug(DBGSCHED, "waking process %d", t->proc->pid);

View file

@ -7,6 +7,7 @@ doexec(void *v)
{ {
char **argv = v; char **argv = v;
print("doexec\n");
procexec(nil, argv[0], argv); procexec(nil, argv[0], argv);
sendp(threadwaitchan(), nil); sendp(threadwaitchan(), nil);
} }
@ -27,8 +28,8 @@ threadmain(int argc, char **argv)
proccreate(doexec, argv, 8192); proccreate(doexec, argv, 8192);
w = recvp(c); w = recvp(c);
if(w == nil) if(w == nil)
print("exec failed\n"); print("exec failed: %r\n");
else else
print("%d %lu %lu %lu %s\n", w->pid, w->time[0], w->time[1], w->time[2], w->msg); print("%d %lud %lud %lud %s\n", w->pid, w->time[0], w->time[1], w->time[2], w->msg);
threadexits(nil); threadexits(nil);
} }