diff options
Diffstat (limited to 'src/libthread')
-rw-r--r-- | src/libthread/386-ucontext.h | 6 | ||||
-rw-r--r-- | src/libthread/BSD.c | 3 | ||||
-rw-r--r-- | src/libthread/Darwin-386.c | 1 | ||||
-rw-r--r-- | src/libthread/Darwin-power.c | 3 | ||||
-rw-r--r-- | src/libthread/Darwin-x86_64-swapcontext.c | 2 | ||||
-rw-r--r-- | src/libthread/Linux-arm-swapcontext.c | 2 | ||||
-rw-r--r-- | src/libthread/Linux-sparc64-swapcontext.c | 1 | ||||
-rw-r--r-- | src/libthread/Linux.c | 13 | ||||
-rw-r--r-- | src/libthread/NetBSD.c | 1 | ||||
-rw-r--r-- | src/libthread/OpenBSD-386.c | 1 | ||||
-rw-r--r-- | src/libthread/OpenBSD-power.c | 1 | ||||
-rw-r--r-- | src/libthread/OpenBSD-x86_64.c | 2 | ||||
-rw-r--r-- | src/libthread/channel.c | 9 | ||||
-rw-r--r-- | src/libthread/daemonize.c | 6 | ||||
-rw-r--r-- | src/libthread/exec.c | 1 | ||||
-rw-r--r-- | src/libthread/ioproc.h | 1 | ||||
-rw-r--r-- | src/libthread/power-ucontext.h | 1 | ||||
-rw-r--r-- | src/libthread/sparc-ucontext.h | 1 | ||||
-rw-r--r-- | src/libthread/test/thello.c | 1 | ||||
-rw-r--r-- | src/libthread/test/tspawnloop.c | 4 | ||||
-rw-r--r-- | src/libthread/thread.c | 84 | ||||
-rw-r--r-- | src/libthread/threadimpl.h | 5 | ||||
-rw-r--r-- | src/libthread/wait.c | 4 | ||||
-rw-r--r-- | src/libthread/x86_64-ucontext.h | 1 |
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*); - |