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.
*/
typedef struct Stack Stack;
struct Stack {
ulong magic;
Thread *thr;
Stack *next;
uchar buf[STKSIZE-12];
};
static Stack *stkfree;
static Lock stklock;
void
_stackfree(void *v)
{
Stack *s;
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;
free(v);
}
static int
@ -62,16 +18,15 @@ newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize, char *name,
{
int id;
Thread *t;
Stack *s;
char *s;
if(stacksize < 32)
sysfatal("bad stacksize %d", stacksize);
t = _threadmalloc(sizeof(Thread), 1);
s = stackalloc();
s->thr = t;
s = _threadmalloc(stacksize, 0);
t->stk = (char*)s;
t->stksize = STKSIZE;
_threaddebugmemset(s->buf, 0xFE, sizeof s->buf);
t->stksize = stacksize;
_threaddebugmemset(s, 0xFE, stacksize);
_threadinitstack(t, f, arg);
t->proc = p;
t->grp = grp;
@ -138,7 +93,7 @@ _freeproc(Proc *p)
if(t->cmdname)
free(t->cmdname);
assert(t->stk != nil);
_stackfree((Stack*)t->stk);
_stackfree(t->stk);
nextt = t->nextt;
free(t);
}

View file

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

View file

@ -1,5 +1,5 @@
#include "threadimpl.h"
#include <signal.h>
#include "threadimpl.h"
char *_threadexitsallstatus;
Channel *_threadwaitchan;
@ -13,6 +13,7 @@ threadexits(char *exitstr)
p = _threadgetproc();
t = p->thread;
t->moribund = 1;
_threaddebug(DBGSCHED, "threadexits %s", exitstr);
if(exitstr==nil)
exitstr="";
utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr);
@ -26,6 +27,7 @@ threadexitsall(char *exitstr)
int *pid;
int i, npid, mypid;
_threaddebug(DBGSCHED, "threadexitsall %s", exitstr);
if(exitstr == nil)
exitstr = "";
_threadexitsallstatus = exitstr;
@ -34,7 +36,7 @@ threadexitsall(char *exitstr)
/*
* 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.
*/
lock(&_threadpq.lock);
@ -46,9 +48,13 @@ threadexitsall(char *exitstr)
for(p = _threadpq.head; p; p=p->next)
pid[npid++] = p->pid;
unlock(&_threadpq.lock);
for(i=0; i<npid; i++)
if(pid[i] != mypid)
for(i=0; i<npid; i++){
_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);
}
/* leave */
exit(0);

View file

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

View file

@ -32,6 +32,14 @@ struct Label
// uvlong fpr[18]; /* callee saved: f14-f31 */
// 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
#error "Unknown or unsupported architecture"
#endif

View file

@ -1,5 +1,5 @@
#include "threadimpl.h"
#include <signal.h>
#include "threadimpl.h"
typedef struct Mainarg Mainarg;
struct Mainarg
@ -74,7 +74,13 @@ _threadsignalpasser(void)
int
_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

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

View file

@ -7,6 +7,7 @@ doexec(void *v)
{
char **argv = v;
print("doexec\n");
procexec(nil, argv[0], argv);
sendp(threadwaitchan(), nil);
}
@ -27,8 +28,8 @@ threadmain(int argc, char **argv)
proccreate(doexec, argv, 8192);
w = recvp(c);
if(w == nil)
print("exec failed\n");
print("exec failed: %r\n");
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);
}