mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-27 11:52:03 +00:00
add threaddaemonize(), more bug fixes
This commit is contained in:
parent
929fcfe0e3
commit
2c87dda8f8
7 changed files with 56 additions and 14 deletions
|
@ -21,6 +21,11 @@ void _threadsleep(Rendez*);
|
||||||
_Thread *_threadwakeup(Rendez*);
|
_Thread *_threadwakeup(Rendez*);
|
||||||
#define yield threadyield
|
#define yield threadyield
|
||||||
|
|
||||||
|
/*
|
||||||
|
* daemonize
|
||||||
|
*/
|
||||||
|
void threaddaemonize(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* per proc and thread data
|
* per proc and thread data
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "threadimpl.h"
|
#include "threadimpl.h"
|
||||||
|
|
||||||
|
int ngetpid;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* spin locks
|
* spin locks
|
||||||
*/
|
*/
|
||||||
|
@ -99,15 +102,12 @@ again:
|
||||||
sigdelset(&mask, SIGUSR1);
|
sigdelset(&mask, SIGUSR1);
|
||||||
sigsuspend(&mask);
|
sigsuspend(&mask);
|
||||||
|
|
||||||
//print("%d %d awake again\n", time(0), getpid());
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're awake. Make USR1 not interrupt system calls.
|
* We're awake. Make USR1 not interrupt system calls.
|
||||||
*/
|
*/
|
||||||
lock(r->l);
|
lock(r->l);
|
||||||
ignusr1(1);
|
ignusr1(1);
|
||||||
if(r->asleep && r->pid == getpid()){
|
if(r->asleep && r->pid == getpid()){
|
||||||
//print("resleep %d\n", getpid());
|
|
||||||
/* Didn't really wake up - signal from something else */
|
/* Didn't really wake up - signal from something else */
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
@ -160,10 +160,14 @@ dofreestacks(void)
|
||||||
next = sf->next;
|
next = sf->next;
|
||||||
if(sf->pid >= 1 && kill(sf->pid, 0) < 0 && errno == ESRCH){
|
if(sf->pid >= 1 && kill(sf->pid, 0) < 0 && errno == ESRCH){
|
||||||
free(sf);
|
free(sf);
|
||||||
|
if(last)
|
||||||
last->next = next;
|
last->next = next;
|
||||||
|
else
|
||||||
|
stackfree = next;
|
||||||
sf = last;
|
sf = last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unlock(&stacklock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -240,7 +244,7 @@ static char *threadexitsmsg;
|
||||||
void
|
void
|
||||||
sigusr2handler(int s)
|
sigusr2handler(int s)
|
||||||
{
|
{
|
||||||
print("%d usr2 %d\n", time(0), getpid());
|
/* fprint(2, "%d usr2 %d\n", time(0), getpid()); */
|
||||||
if(threadexitsmsg)
|
if(threadexitsmsg)
|
||||||
_exits(threadexitsmsg);
|
_exits(threadexitsmsg);
|
||||||
}
|
}
|
||||||
|
@ -341,6 +345,7 @@ _threadsetproc(Proc *p)
|
||||||
{
|
{
|
||||||
Perproc *pp;
|
Perproc *pp;
|
||||||
|
|
||||||
|
if(p)
|
||||||
p->osprocid = getpid();
|
p->osprocid = getpid();
|
||||||
pp = newperproc();
|
pp = newperproc();
|
||||||
pp->proc = p;
|
pp->proc = p;
|
||||||
|
|
|
@ -20,6 +20,8 @@ static void
|
||||||
xioproc(void *a)
|
xioproc(void *a)
|
||||||
{
|
{
|
||||||
Ioproc *io, *x;
|
Ioproc *io, *x;
|
||||||
|
|
||||||
|
threadsetname("ioproc");
|
||||||
io = a;
|
io = a;
|
||||||
/*
|
/*
|
||||||
* first recvp acquires the ioproc.
|
* first recvp acquires the ioproc.
|
||||||
|
|
|
@ -6,6 +6,7 @@ LIB=libthread.a
|
||||||
OFILES=\
|
OFILES=\
|
||||||
$SYSOFILES\
|
$SYSOFILES\
|
||||||
channel.$O\
|
channel.$O\
|
||||||
|
daemonize.$O\
|
||||||
exec.$O\
|
exec.$O\
|
||||||
ioproc.$O\
|
ioproc.$O\
|
||||||
iorw.$O\
|
iorw.$O\
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
SHORTLIB=thread 9
|
SHORTLIB=thread 9
|
||||||
OFILES=
|
OFILES=
|
||||||
|
|
||||||
TARG=tprimes tspawn tspawnloop
|
TARG=tprimes tspawn tspawnloop tdaemon
|
||||||
|
|
||||||
<$PLAN9/src/mkmany
|
<$PLAN9/src/mkmany
|
||||||
|
|
|
@ -20,6 +20,25 @@ static void delthreadinproc(Proc*, _Thread*);
|
||||||
static void contextswitch(Context *from, Context *to);
|
static void contextswitch(Context *from, Context *to);
|
||||||
static void scheduler(Proc*);
|
static void scheduler(Proc*);
|
||||||
|
|
||||||
|
static void
|
||||||
|
_threaddebug(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
char buf[128];
|
||||||
|
_Thread *t;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_start(arg, fmt);
|
||||||
|
vsnprint(buf, sizeof buf, fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
t = proc()->thread;
|
||||||
|
if(t)
|
||||||
|
fprint(2, "%d.%d: %s\n", getpid(), t->id, buf);
|
||||||
|
else
|
||||||
|
fprint(2, "%d._: %s\n", getpid(), buf);
|
||||||
|
}
|
||||||
|
|
||||||
static _Thread*
|
static _Thread*
|
||||||
getthreadnow(void)
|
getthreadnow(void)
|
||||||
{
|
{
|
||||||
|
@ -50,6 +69,7 @@ threadstart(void *v)
|
||||||
|
|
||||||
t = v;
|
t = v;
|
||||||
t->startfn(t->startarg);
|
t->startfn(t->startarg);
|
||||||
|
memset(&v, 0xff, 32); /* try to cut off stack traces */
|
||||||
threadexits(nil);
|
threadexits(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +101,7 @@ threadalloc(void (*fn)(void*), void *arg, uint stack)
|
||||||
/* call makecontext to do the real work. */
|
/* call makecontext to do the real work. */
|
||||||
/* leave a few words open on both ends */
|
/* leave a few words open on both ends */
|
||||||
t->context.uc.uc_stack.ss_sp = t->stk+8;
|
t->context.uc.uc_stack.ss_sp = t->stk+8;
|
||||||
t->context.uc.uc_stack.ss_size = t->stksize-16;
|
t->context.uc.uc_stack.ss_size = t->stksize-64;
|
||||||
makecontext(&t->context.uc, (void(*)())threadstart, 1, t);
|
makecontext(&t->context.uc, (void(*)())threadstart, 1, t);
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
|
@ -185,6 +205,7 @@ scheduler(Proc *p)
|
||||||
_Thread *t;
|
_Thread *t;
|
||||||
|
|
||||||
setproc(p);
|
setproc(p);
|
||||||
|
_threaddebug("scheduler enter");
|
||||||
// print("s %p %d\n", p, gettid());
|
// print("s %p %d\n", p, gettid());
|
||||||
lock(&p->lock);
|
lock(&p->lock);
|
||||||
for(;;){
|
for(;;){
|
||||||
|
@ -192,15 +213,15 @@ scheduler(Proc *p)
|
||||||
if(p->nthread == 0)
|
if(p->nthread == 0)
|
||||||
goto Out;
|
goto Out;
|
||||||
p->runrend.l = &p->lock;
|
p->runrend.l = &p->lock;
|
||||||
//print("%d sleep for jobs %d\n", time(0), getpid());
|
_threaddebug("scheduler sleep");
|
||||||
_procsleep(&p->runrend);
|
_procsleep(&p->runrend);
|
||||||
//print("%d wake from jobs %d\n", time(0), getpid());
|
_threaddebug("scheduler wake");
|
||||||
}
|
}
|
||||||
delthread(&p->runqueue, t);
|
delthread(&p->runqueue, t);
|
||||||
unlock(&p->lock);
|
unlock(&p->lock);
|
||||||
p->thread = t;
|
p->thread = t;
|
||||||
p->nswitch++;
|
p->nswitch++;
|
||||||
// print("run %s %d\n", t->name, t->id);
|
_threaddebug("run %d (%s)", t->id, t->name);
|
||||||
contextswitch(&p->schedcontext, &t->context);
|
contextswitch(&p->schedcontext, &t->context);
|
||||||
p->thread = nil;
|
p->thread = nil;
|
||||||
lock(&p->lock);
|
lock(&p->lock);
|
||||||
|
@ -212,6 +233,7 @@ scheduler(Proc *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
Out:
|
Out:
|
||||||
|
_threaddebug("scheduler exit");
|
||||||
delproc(p);
|
delproc(p);
|
||||||
lock(&threadnproclock);
|
lock(&threadnproclock);
|
||||||
if(p->sysproc)
|
if(p->sysproc)
|
||||||
|
@ -447,11 +469,18 @@ threadmainstart(void *v)
|
||||||
threadmain(threadargc, threadargv);
|
threadmain(threadargc, threadargv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
threadlinklibrary(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Proc *p;
|
Proc *p;
|
||||||
|
|
||||||
|
_threadsetupdaemonize();
|
||||||
|
|
||||||
threadargc = argc;
|
threadargc = argc;
|
||||||
threadargv = argv;
|
threadargv = argv;
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ typedef struct Execjob Execjob;
|
||||||
typedef struct Proc Proc;
|
typedef struct Proc Proc;
|
||||||
typedef struct _Procrendez _Procrendez;
|
typedef struct _Procrendez _Procrendez;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct Jmp Jmp;
|
typedef struct Jmp Jmp;
|
||||||
struct Jmp
|
struct Jmp
|
||||||
{
|
{
|
||||||
|
@ -106,3 +104,5 @@ extern void _threadunlock(Lock*, ulong);
|
||||||
extern void _pthreadinit(void);
|
extern void _pthreadinit(void);
|
||||||
extern int _threadspawn(int*, char*, char**);
|
extern int _threadspawn(int*, char*, char**);
|
||||||
extern int _runthreadspawn(int*, char*, char**);
|
extern int _runthreadspawn(int*, char*, char**);
|
||||||
|
extern void _threadsetupdaemonize(void);
|
||||||
|
extern void _threaddodaemonize(char*);
|
||||||
|
|
Loading…
Reference in a new issue