aboutsummaryrefslogtreecommitdiff
path: root/src/libthread
diff options
context:
space:
mode:
Diffstat (limited to 'src/libthread')
-rw-r--r--src/libthread/386-ucontext.h6
-rw-r--r--src/libthread/BSD.c3
-rw-r--r--src/libthread/Darwin-386.c1
-rw-r--r--src/libthread/Darwin-power.c3
-rw-r--r--src/libthread/Darwin-x86_64-swapcontext.c2
-rw-r--r--src/libthread/Linux-arm-swapcontext.c2
-rw-r--r--src/libthread/Linux-sparc64-swapcontext.c1
-rw-r--r--src/libthread/Linux.c13
-rw-r--r--src/libthread/NetBSD.c1
-rw-r--r--src/libthread/OpenBSD-386.c1
-rw-r--r--src/libthread/OpenBSD-power.c1
-rw-r--r--src/libthread/OpenBSD-x86_64.c2
-rw-r--r--src/libthread/channel.c9
-rw-r--r--src/libthread/daemonize.c6
-rw-r--r--src/libthread/exec.c1
-rw-r--r--src/libthread/ioproc.h1
-rw-r--r--src/libthread/power-ucontext.h1
-rw-r--r--src/libthread/sparc-ucontext.h1
-rw-r--r--src/libthread/test/thello.c1
-rw-r--r--src/libthread/test/tspawnloop.c4
-rw-r--r--src/libthread/thread.c84
-rw-r--r--src/libthread/threadimpl.h5
-rw-r--r--src/libthread/wait.c4
-rw-r--r--src/libthread/x86_64-ucontext.h1
24 files changed, 80 insertions, 74 deletions
diff --git a/src/libthread/386-ucontext.h b/src/libthread/386-ucontext.h
index 21327d9b..b1ee81b3 100644
--- a/src/libthread/386-ucontext.h
+++ b/src/libthread/386-ucontext.h
@@ -16,7 +16,7 @@ extern void setmcontext(mcontext_t*);
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
+ * notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
@@ -48,7 +48,7 @@ extern void setmcontext(mcontext_t*);
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
+ * notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
@@ -117,5 +117,3 @@ struct ucontext {
stack_t uc_stack;
int __spare__[8];
};
-
-
diff --git a/src/libthread/BSD.c b/src/libthread/BSD.c
index b9e8888e..737c0a63 100644
--- a/src/libthread/BSD.c
+++ b/src/libthread/BSD.c
@@ -288,7 +288,7 @@ threadexitsall(char *msg)
if(msg == nil)
msg = "";
- /*
+ /*
* Only one guy, ever, gets to run this.
* If two guys do it, inevitably they end up
* tripping over each other in the underlying
@@ -401,4 +401,3 @@ _threadpexit(void)
{
_exit(0);
}
-
diff --git a/src/libthread/Darwin-386.c b/src/libthread/Darwin-386.c
index 3ad1941c..b138e420 100644
--- a/src/libthread/Darwin-386.c
+++ b/src/libthread/Darwin-386.c
@@ -28,4 +28,3 @@ swapcontext(ucontext_t *oucp, ucontext_t *ucp)
setcontext(ucp);
return 0;
}
-
diff --git a/src/libthread/Darwin-power.c b/src/libthread/Darwin-power.c
index efcdb18c..3f2bf566 100644
--- a/src/libthread/Darwin-power.c
+++ b/src/libthread/Darwin-power.c
@@ -7,7 +7,7 @@ makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
va_list arg;
tos = (ulong*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/sizeof(ulong);
- sp = tos - 16;
+ sp = tos - 16;
ucp->mc.pc = (long)func;
ucp->mc.sp = (long)sp;
va_start(arg, argc);
@@ -22,4 +22,3 @@ swapcontext(ucontext_t *oucp, ucontext_t *ucp)
setcontext(ucp);
return 0;
}
-
diff --git a/src/libthread/Darwin-x86_64-swapcontext.c b/src/libthread/Darwin-x86_64-swapcontext.c
index 0593e481..27931456 100644
--- a/src/libthread/Darwin-x86_64-swapcontext.c
+++ b/src/libthread/Darwin-x86_64-swapcontext.c
@@ -28,5 +28,3 @@ swapcontext(ucontext_t *oucp, ucontext_t *ucp)
setcontext(ucp);
return 0;
}
-
-
diff --git a/src/libthread/Linux-arm-swapcontext.c b/src/libthread/Linux-arm-swapcontext.c
index 907fb0c3..fc0dfdda 100644
--- a/src/libthread/Linux-arm-swapcontext.c
+++ b/src/libthread/Linux-arm-swapcontext.c
@@ -22,5 +22,3 @@ swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
setcontext(ucp);
return 0;
}
-
-
diff --git a/src/libthread/Linux-sparc64-swapcontext.c b/src/libthread/Linux-sparc64-swapcontext.c
index a621b7a1..e4800c19 100644
--- a/src/libthread/Linux-sparc64-swapcontext.c
+++ b/src/libthread/Linux-sparc64-swapcontext.c
@@ -47,4 +47,3 @@ __swapcontext_ret: \n\
clr %o0 \n\
.size __swapcontext_ret, .-__swapcontext_ret \n\
");
-
diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c
index 17e8c12b..31577e87 100644
--- a/src/libthread/Linux.c
+++ b/src/libthread/Linux.c
@@ -6,13 +6,13 @@
static int
timefmt(Fmt *fmt)
{
- static char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ static char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
vlong ns;
Tm tm;
ns = nsec();
tm = *localtime(time(0));
- return fmtprint(fmt, "%s %2d %02d:%02d:%02d.%03d",
+ return fmtprint(fmt, "%s %2d %02d:%02d:%02d.%03d",
mon[tm.mon], tm.mday, tm.hour, tm.min, tm.sec,
(int)(ns%1000000000)/1000000);
}
@@ -246,8 +246,8 @@ startprocfn(void *v)
/*
* indirect through here so that parent need not wait for child zombie
- *
- * slight race - if child exits and then another process starts before we
+ *
+ * slight race - if child exits and then another process starts before we
* manage to exit, we'll be running on a freed stack.
*/
static int
@@ -314,7 +314,7 @@ threadexitsall(char *msg)
if(msg == nil)
msg = "";
- /*
+ /*
* Only one guy, ever, gets to run this.
* If two guys do it, inevitably they end up
* tripping over each other in the underlying
@@ -442,7 +442,7 @@ makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
{
int i, *sp;
va_list arg;
-
+
sp = (int*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size/4;
va_start(arg, argc);
for(i=0; i<4 && i<argc; i++)
@@ -460,4 +460,3 @@ swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
return 0;
}
#endif
-
diff --git a/src/libthread/NetBSD.c b/src/libthread/NetBSD.c
index cb195149..37dabe9c 100644
--- a/src/libthread/NetBSD.c
+++ b/src/libthread/NetBSD.c
@@ -1,2 +1 @@
#include "Linux.c"
-
diff --git a/src/libthread/OpenBSD-386.c b/src/libthread/OpenBSD-386.c
index 3725f264..89bfedcd 100644
--- a/src/libthread/OpenBSD-386.c
+++ b/src/libthread/OpenBSD-386.c
@@ -20,4 +20,3 @@ swapcontext(ucontext_t *oucp, ucontext_t *ucp)
setcontext(ucp);
return 0;
}
-
diff --git a/src/libthread/OpenBSD-power.c b/src/libthread/OpenBSD-power.c
index b83522f0..eab711f2 100644
--- a/src/libthread/OpenBSD-power.c
+++ b/src/libthread/OpenBSD-power.c
@@ -22,4 +22,3 @@ swapcontext(ucontext_t *oucp, ucontext_t *ucp)
setcontext(ucp);
return 0;
}
-
diff --git a/src/libthread/OpenBSD-x86_64.c b/src/libthread/OpenBSD-x86_64.c
index 0593e481..27931456 100644
--- a/src/libthread/OpenBSD-x86_64.c
+++ b/src/libthread/OpenBSD-x86_64.c
@@ -28,5 +28,3 @@ swapcontext(ucontext_t *oucp, ucontext_t *ucp)
setcontext(ucp);
return 0;
}
-
-
diff --git a/src/libthread/channel.c b/src/libthread/channel.c
index cd7750c0..53af86e6 100644
--- a/src/libthread/channel.c
+++ b/src/libthread/channel.c
@@ -5,10 +5,10 @@
* You have to put locks in all the channels and all the Alt
* structures. At the beginning of an alt you have to lock all
* the channels, but then to try to actually exec an op you
- * have to lock the other guy's alt structure, so that other
+ * have to lock the other guy's alt structure, so that other
* people aren't trying to use him in some other op at the
* same time.
- *
+ *
* For Plan 9 apps, it's just not worth the extra effort.
*/
static QLock chanlock;
@@ -397,7 +397,7 @@ chanrecvul(Channel *c)
if(_chanop(c, CHANRCV, &val, 1) > 0)
return val;
- return -1;
+ return 0;
}
int
@@ -413,6 +413,5 @@ channbrecvul(Channel *c)
if(_chanop(c, CHANRCV, &val, 0) > 0)
return val;
- return -1;
+ return 0;
}
-
diff --git a/src/libthread/daemonize.c b/src/libthread/daemonize.c
index e047ab02..387d1527 100644
--- a/src/libthread/daemonize.c
+++ b/src/libthread/daemonize.c
@@ -66,13 +66,13 @@ sigpass(int sig)
kill(sigpid, sig);
}
-static int sigs[] =
+static int sigs[] =
{
SIGHUP, SIGINT, SIGQUIT, SIGILL,
SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE,
SIGALRM, SIGTERM, SIGCHLD, SIGSTOP,
- /*SIGTSTP, SIGTTIN, SIGTTOU,*/ SIGURG,
+ /*SIGTSTP, SIGTTIN, SIGTTOU,*/ SIGURG,
SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF,
#ifdef SIGWINCH
SIGWINCH,
@@ -84,7 +84,7 @@ static int sigs[] =
SIGEMT,
#endif
#ifdef SIGPWR
- SIGPWR,
+ SIGPWR,
#endif
#ifdef SIGINFO
SIGINFO,
diff --git a/src/libthread/exec.c b/src/libthread/exec.c
index 62805ba2..fb5d521a 100644
--- a/src/libthread/exec.c
+++ b/src/libthread/exec.c
@@ -206,4 +206,3 @@ threadexecl(Channel *cpid, int fd[3], char *cmd, ...)
if(pid >= 0)
threadexits("threadexecl");
}
-
diff --git a/src/libthread/ioproc.h b/src/libthread/ioproc.h
index f3a488d3..831beade 100644
--- a/src/libthread/ioproc.h
+++ b/src/libthread/ioproc.h
@@ -11,4 +11,3 @@ struct Ioproc
char err[ERRMAX];
Ioproc *next;
};
-
diff --git a/src/libthread/power-ucontext.h b/src/libthread/power-ucontext.h
index 27ed3390..1985d98d 100644
--- a/src/libthread/power-ucontext.h
+++ b/src/libthread/power-ucontext.h
@@ -34,4 +34,3 @@ void makecontext(ucontext_t*, void(*)(void), int, ...);
int swapcontext(ucontext_t*, ucontext_t*);
int _getmcontext(mcontext_t*);
void _setmcontext(mcontext_t*);
-
diff --git a/src/libthread/sparc-ucontext.h b/src/libthread/sparc-ucontext.h
index 0031d2a4..36b88171 100644
--- a/src/libthread/sparc-ucontext.h
+++ b/src/libthread/sparc-ucontext.h
@@ -21,4 +21,3 @@ void makecontext(ucontext_t*, void(*)(void), int, ...);
int swapcontext(ucontext_t*, ucontext_t*);
int _getmcontext(mcontext_t*);
void _setmcontext(mcontext_t*);
-
diff --git a/src/libthread/test/thello.c b/src/libthread/test/thello.c
index c5732165..c237b7cd 100644
--- a/src/libthread/test/thello.c
+++ b/src/libthread/test/thello.c
@@ -7,4 +7,3 @@ threadmain(int argc, char **argv)
{
print("hello, world\n");
}
-
diff --git a/src/libthread/test/tspawnloop.c b/src/libthread/test/tspawnloop.c
index 05636dc9..204328b8 100644
--- a/src/libthread/test/tspawnloop.c
+++ b/src/libthread/test/tspawnloop.c
@@ -8,7 +8,7 @@ execproc(void *v)
int i, fd[3];
char buf[100], *args[3];
- i = (int)v;
+ i = (int)(uintptr)v;
sprint(buf, "%d", i);
fd[0] = dup(0, -1);
fd[1] = dup(1, -1);
@@ -33,7 +33,7 @@ threadmain(int argc, char **argv)
c = threadwaitchan();
for(i=0;; i++){
- proccreate(execproc, (void*)i, 16384);
+ proccreate(execproc, (void*)(uintptr)i, 16384);
w = recvp(c);
if(w == nil)
sysfatal("exec/recvp failed: %r");
diff --git a/src/libthread/thread.c b/src/libthread/thread.c
index 542a2437..d041efcc 100644
--- a/src/libthread/thread.c
+++ b/src/libthread/thread.c
@@ -16,6 +16,7 @@ static int onlist(_Threadlist*, _Thread*);
static void addthreadinproc(Proc*, _Thread*);
static void delthreadinproc(Proc*, _Thread*);
static void contextswitch(Context *from, Context *to);
+static void procmain(Proc*);
static void procscheduler(Proc*);
static int threadinfo(void*, char*);
@@ -112,8 +113,6 @@ threadalloc(void (*fn)(void*), void *arg, uint stack)
if(t == nil)
sysfatal("threadalloc malloc: %r");
memset(t, 0, sizeof *t);
- t->stk = (uchar*)(t+1);
- t->stksize = stack;
t->id = incref(&threadidref);
//print("fn=%p arg=%p\n", fn, arg);
t->startfn = fn;
@@ -121,6 +120,10 @@ threadalloc(void (*fn)(void*), void *arg, uint stack)
//print("makecontext sp=%p t=%p startfn=%p\n", (char*)t->stk+t->stksize, t, t->startfn);
/* do a reasonable initialization */
+ if(stack == 0)
+ return t;
+ t->stk = (uchar*)(t+1);
+ t->stksize = stack;
memset(&t->context.uc, 0, sizeof t->context.uc);
sigemptyset(&zero);
sigprocmask(SIG_BLOCK, &zero, &t->context.uc.uc_sigmask);
@@ -137,7 +140,7 @@ threadalloc(void (*fn)(void*), void *arg, uint stack)
t->context.uc.uc_stack.ss_size = t->stksize-64;
#if defined(__sun__) && !defined(__MAKECONTEXT_V2_SOURCE) /* sigh */
/* can avoid this with __MAKECONTEXT_V2_SOURCE but only on SunOS 5.9 */
- t->context.uc.uc_stack.ss_sp =
+ t->context.uc.uc_stack.ss_sp =
(char*)t->context.uc.uc_stack.ss_sp
+t->context.uc.uc_stack.ss_size;
#endif
@@ -164,7 +167,9 @@ _threadcreate(Proc *p, void (*fn)(void*), void *arg, uint stack)
/* defend against bad C libraries */
if(stack < (256<<10))
stack = 256<<10;
-
+
+ if(p->nthread == 0)
+ stack = 0; // not using it
t = threadalloc(fn, arg, stack);
t->proc = p;
addthreadinproc(p, t);
@@ -192,7 +197,7 @@ proccreate(void (*fn)(void*), void *arg, uint stack)
p = procalloc();
t = _threadcreate(p, fn, arg, stack);
id = t->id; /* t might be freed after _procstart */
- _procstart(p, procscheduler);
+ _procstart(p, procmain);
return id;
}
@@ -204,7 +209,10 @@ _threadswitch(void)
needstack(0);
p = proc();
/*print("threadswtch %p\n", p); */
- contextswitch(&p->thread->context, &p->schedcontext);
+ if(p->thread->stk == nil)
+ procscheduler(p);
+ else
+ contextswitch(&p->thread->context, &p->schedcontext);
}
void
@@ -228,7 +236,7 @@ threadidle(void)
{
int n;
Proc *p;
-
+
p = proc();
n = p->nswitch;
lock(&p->lock);
@@ -312,14 +320,42 @@ contextswitch(Context *from, Context *to)
}
static void
+procmain(Proc *p)
+{
+ _Thread *t;
+
+ _threadsetproc(p);
+
+ /* take out first thread to run on system stack */
+ t = p->runqueue.head;
+ delthread(&p->runqueue, t);
+ memset(&t->context.uc, 0, sizeof t->context.uc);
+
+ /* run it */
+ p->thread = t;
+ t->startfn(t->startarg);
+ if(p->nthread != 0)
+ threadexits(nil);
+}
+
+static void
procscheduler(Proc *p)
{
_Thread *t;
- setproc(p);
_threaddebug("scheduler enter");
//print("s %p\n", p);
+Top:
lock(&p->lock);
+ t = p->thread;
+ p->thread = nil;
+ if(t->exiting){
+ delthreadinproc(p, t);
+ p->nthread--;
+/*print("nthread %d\n", p->nthread); */
+ free(t);
+ }
+
for(;;){
if((t = p->pinthread) != nil){
while(!onlist(&p->runqueue, t)){
@@ -356,16 +392,11 @@ procscheduler(Proc *p)
p->nswitch++;
_threaddebug("run %d (%s)", t->id, t->name);
//print("run %p %p %p %p\n", t, *(uintptr*)(t->context.uc.mc.sp), t->context.uc.mc.di, t->context.uc.mc.si);
+ if(t->stk == nil)
+ return;
contextswitch(&p->schedcontext, &t->context);
/*print("back in scheduler\n"); */
- p->thread = nil;
- lock(&p->lock);
- if(t->exiting){
- delthreadinproc(p, t);
- p->nthread--;
-/*print("nthread %d\n", p->nthread); */
- free(t);
- }
+ goto Top;
}
Out:
@@ -398,6 +429,7 @@ Out:
unlock(&p->lock);
_threadsetproc(nil);
free(p);
+ _threadpexit();
}
void
@@ -466,7 +498,7 @@ int
threadid(void)
{
_Thread *t;
-
+
t = proc()->thread;
return t->id;
}
@@ -534,7 +566,7 @@ static void
threadqunlock(QLock *l, ulong pc)
{
_Thread *ready;
-
+
lock(&l->l);
/*print("qlock unlock %p @%#x by %p (owner %p)\n", l, pc, (*threadnow)(), l->owner); */
if(l->owner == 0){
@@ -578,7 +610,7 @@ threadrlock(RWLock *l, int block, ulong pc)
addthread(&l->rwaiting, (*threadnow)());
unlock(&l->l);
_threadswitch();
- return 1;
+ return 1;
}
static int
@@ -677,7 +709,7 @@ threadrwakeup(Rendez *r, int all, ulong pc)
if((t = r->waiting.head) == nil)
break;
delthread(&r->waiting, t);
- _threadready(t);
+ _threadready(t);
}
return i;
}
@@ -749,7 +781,7 @@ main(int argc, char **argv)
mainstacksize = 256*1024;
atnotify(threadinfo, 1);
_threadcreate(p, threadmainstart, nil, mainstacksize);
- procscheduler(p);
+ procmain(p);
sysfatal("procscheduler returned in threadmain!");
/* does not return */
return 0;
@@ -865,7 +897,7 @@ delproc(Proc *p)
unlock(&_threadprocslock);
}
-/*
+/*
* notify - for now just use the usual mechanisms
*/
void
@@ -901,14 +933,12 @@ threadinfo(void *v, char *s)
fprint(2, "proc %p %s%s\n", (void*)p->osprocid, p->msg,
p->sysproc ? " (sysproc)": "");
for(t=p->allthreads.head; t; t=t->allnext){
- fprint(2, "\tthread %d %s: %s %s\n",
- t->id,
- t == p->thread ? "Running" :
+ fprint(2, "\tthread %d %s: %s %s\n",
+ t->id,
+ t == p->thread ? "Running" :
onrunqueue(p, t) ? "Ready" : "Sleeping",
t->state, t->name);
}
}
return 1;
}
-
-
diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
index 144a2136..76ca57e5 100644
--- a/src/libthread/threadimpl.h
+++ b/src/libthread/threadimpl.h
@@ -28,7 +28,7 @@ extern void makecontext(ucontext_t*, void(*)(), int, ...);
/*
* OS X before 10.5 (Leopard) does not provide
* swapcontext nor makecontext, so we have to use our own.
- * In theory, Leopard does provide them, but when we use
+ * In theory, Leopard does provide them, but when we use
* them, they seg fault. Maybe we're using them wrong.
* So just use our own versions, even on Leopard.
*/
@@ -187,7 +187,6 @@ struct Proc
};
#define proc() _threadproc()
-#define setproc(p) _threadsetproc(p)
extern Proc *_threadprocs;
extern Lock _threadprocslock;
@@ -198,7 +197,7 @@ extern Channel *_dowaitchan;
extern void _procstart(Proc*, void (*fn)(Proc*));
extern _Thread *_threadcreate(Proc*, void(*fn)(void*), void*, uint);
-extern void _threadexit(void);
+extern void _procexit(void);
extern Proc *_threadproc(void);
extern void _threadsetproc(Proc*);
extern int _threadlock(Lock*, int, ulong);
diff --git a/src/libthread/wait.c b/src/libthread/wait.c
index 24538e58..ba2301f5 100644
--- a/src/libthread/wait.c
+++ b/src/libthread/wait.c
@@ -29,11 +29,11 @@ procwait(int pid)
Waiter me;
Waitmsg *msg;
int i;
-
+
memset(&me, 0, sizeof me);
me.pid = pid;
me.r.l = &waiting.lk;
-
+
qlock(&waiting.lk);
for(i=0; i<waiting.nmsg; i++){
if(waiting.msg[i]->pid == pid){
diff --git a/src/libthread/x86_64-ucontext.h b/src/libthread/x86_64-ucontext.h
index 08c6d9a8..e0640761 100644
--- a/src/libthread/x86_64-ucontext.h
+++ b/src/libthread/x86_64-ucontext.h
@@ -40,4 +40,3 @@ void makecontext(ucontext_t*, void(*)(void), int, ...);
int swapcontext(ucontext_t*, ucontext_t*);
int libthread_getmcontext(mcontext_t*);
void libthread_setmcontext(mcontext_t*);
-