diff options
-rw-r--r-- | src/libthread/mkfile | 4 | ||||
-rw-r--r-- | src/libthread/pthread.c | 6 | ||||
-rw-r--r-- | src/libthread/test/tprimes.c | 1 | ||||
-rw-r--r-- | src/libthread/thread.c | 173 | ||||
-rw-r--r-- | src/libthread/threadimpl.h | 17 |
5 files changed, 122 insertions, 79 deletions
diff --git a/src/libthread/mkfile b/src/libthread/mkfile index 0be8aec4..a301d48f 100644 --- a/src/libthread/mkfile +++ b/src/libthread/mkfile @@ -1,12 +1,14 @@ <$PLAN9/src/mkhdr +SYSOFILES=`{sh ./sysofiles.sh} + LIB=libthread.a OFILES=\ + $SYSOFILES\ channel.$O\ exec.$O\ ioproc.$O\ iorw.$O\ - pthread.$O\ ref.$O\ thread.$O\ diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c index 6540605d..2ddd8c72 100644 --- a/src/libthread/pthread.c +++ b/src/libthread/pthread.c @@ -82,8 +82,8 @@ startprocfn(void *v) fn = a[0]; p = a[1]; free(a); - p->tid = pthread_self(); - pthread_detach(p->tid); + p->osprocid = pthread_self(); + pthread_detach(p->osprocid); (*fn)(p); @@ -101,7 +101,7 @@ _procstart(Proc *p, void (*fn)(Proc*)) a[0] = fn; a[1] = p; - if(pthread_create(&p->tid, nil, (void*(*)(void*))startprocfn, (void*)a) < 0){ + if(pthread_create(&p->osprocid, nil, (void*(*)(void*))startprocfn, (void*)a) < 0){ fprint(2, "pthread_create: %r\n"); abort(); } diff --git a/src/libthread/test/tprimes.c b/src/libthread/test/tprimes.c index 91af5a73..8fcfa2e2 100644 --- a/src/libthread/test/tprimes.c +++ b/src/libthread/test/tprimes.c @@ -77,4 +77,5 @@ threadmain(int argc, char **argv) c = chancreate(sizeof(ulong), nbuf); mk(countthread, c, STACK); mk(filterthread, c, STACK); + recvp(chancreate(sizeof(void*), 0)); } diff --git a/src/libthread/thread.c b/src/libthread/thread.c index 158f6e9c..4116ac22 100644 --- a/src/libthread/thread.c +++ b/src/libthread/thread.c @@ -1,18 +1,18 @@ #include "u.h" -#include <linux/unistd.h> #include "libc.h" #include "thread.h" #include "threadimpl.h" - _syscall0(pid_t,gettid) - int _threaddebuglevel; static uint threadnproc; static uint threadnsysproc; static Lock threadnproclock; static Ref threadidref; +static Proc *threadmainproc; +static void addproc(Proc*); +static void delproc(Proc*); static void addthread(_Threadlist*, _Thread*); static void delthread(_Threadlist*, _Thread*); static void addthreadinproc(Proc*, _Thread*); @@ -36,6 +36,7 @@ procalloc(void) if(p == nil) sysfatal("procalloc malloc: %r"); memset(p, 0, sizeof *p); + addproc(p); lock(&threadnproclock); threadnproc++; unlock(&threadnproclock); @@ -49,7 +50,7 @@ threadstart(void *v) t = v; t->startfn(t->startarg); - _threadexit(); + threadexits(nil); } static _Thread* @@ -115,9 +116,7 @@ proccreate(void (*fn)(void*), void *arg, uint stack) Proc *p; p = procalloc(); -//print("pa %p\n", p); t = _threadcreate(p, fn, arg, stack); -//print("ps %p\n", p); _procstart(p, scheduler); return t->id; } @@ -151,30 +150,16 @@ threadyield(void) } void -_threadexit(void) -{ - proc()->thread->exiting = 1; - _threadswitch(); -} - -void threadexits(char *msg) { -/* Proc *p; p = proc(); + if(msg == nil) + msg = ""; utfecpy(p->msg, p->msg+sizeof p->msg, msg); -*/ - _threadexit(); -} - -void -threadexitsall(char *msg) -{ - if(msg && msg[0]) - exit(1); - exit(0); + proc()->thread->exiting = 1; + _threadswitch(); } static void @@ -216,11 +201,12 @@ scheduler(Proc *p) } Out: + delproc(p); lock(&threadnproclock); if(p->sysproc) --threadnsysproc; if(--threadnproc == threadnsysproc) - exit(0); + threadexitsall(p->msg); unlock(&threadnproclock); unlock(&p->lock); free(p); @@ -237,6 +223,19 @@ _threadsetsysproc(void) proc()->sysproc = 1; } +void** +procdata(void) +{ + return &proc()->udata; +} + +extern Jmp *(*_notejmpbuf)(void); +static Jmp* +threadnotejmp(void) +{ + return &proc()->sigjmp; +} + /* * debugging */ @@ -422,6 +421,55 @@ threadrwakeup(Rendez *r, int all, ulong pc) } /* + * startup + */ + +static int threadargc; +static char **threadargv; +int mainstacksize; + +static void +threadmainstart(void *v) +{ + USED(v); + threadmainproc = proc(); + threadmain(threadargc, threadargv); +} + +int +main(int argc, char **argv) +{ + Proc *p; + + threadargc = argc; + threadargv = argv; + + /* + * Install locking routines into C library. + */ + _lock = _threadlock; + _unlock = _threadunlock; + _qlock = threadqlock; + _qunlock = threadqunlock; + _rlock = threadrlock; + _runlock = threadrunlock; + _wlock = threadwlock; + _wunlock = threadwunlock; + _rsleep = threadrsleep; + _rwakeup = threadrwakeup; + _notejmpbuf = threadnotejmp; + + _pthreadinit(); + p = procalloc(); + _threadsetproc(p); + if(mainstacksize == 0) + mainstacksize = 65536; + _threadcreate(p, threadmainstart, nil, mainstacksize); + scheduler(p); + return 0; /* not reached */ +} + +/* * hooray for linked lists */ static void @@ -484,58 +532,37 @@ delthreadinproc(Proc *p, _Thread *t) l->tail = t->allprev; } -void** -procdata(void) -{ - return &proc()->udata; -} - -static int threadargc; -static char **threadargv; -int mainstacksize; +Proc *_threadprocs; +Lock _threadprocslock; +static Proc *_threadprocstail; static void -threadmainstart(void *v) -{ - USED(v); - threadmain(threadargc, threadargv); -} - -extern Jmp *(*_notejmpbuf)(void); -static Jmp* -threadnotejmp(void) +addproc(Proc *p) { - return &proc()->sigjmp; + lock(&_threadprocslock); + if(_threadprocstail){ + _threadprocstail->next = p; + p->prev = _threadprocstail; + }else{ + _threadprocs = p; + p->prev = nil; + } + _threadprocstail = p; + p->next = nil; + unlock(&_threadprocslock); } -int -main(int argc, char **argv) +static void +delproc(Proc *p) { - Proc *p; - - threadargc = argc; - threadargv = argv; - - /* - * Install locking routines into C library. - */ - _lock = _threadlock; - _unlock = _threadunlock; - _qlock = threadqlock; - _qunlock = threadqunlock; - _rlock = threadrlock; - _runlock = threadrunlock; - _wlock = threadwlock; - _wunlock = threadwunlock; - _rsleep = threadrsleep; - _rwakeup = threadrwakeup; - _notejmpbuf = threadnotejmp; - - _pthreadinit(); - p = procalloc(); - if(mainstacksize == 0) - mainstacksize = 65536; - _threadcreate(p, threadmainstart, nil, mainstacksize); - scheduler(p); - return 0; /* not reached */ + lock(&_threadprocslock); + if(p->prev) + p->prev->next = p->next; + else + _threadprocs = p->next; + if(p->next) + p->next->prev = p->prev; + else + _threadprocstail = p->prev; + unlock(&_threadprocslock); } diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index e88e321c..d30d58b6 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -42,7 +42,11 @@ struct _Procrendez { Lock *l; int asleep; +#ifdef PLAN9PORT_USING_PTHREADS pthread_cond_t cond; +#else + int pid; +#endif }; extern void _procsleep(_Procrendez*); @@ -50,7 +54,14 @@ extern void _procwakeup(_Procrendez*); struct Proc { - pthread_t tid; + Proc *next; + Proc *prev; + char msg[128]; +#ifdef PLAN9PORT_USING_PTHREADS + pthread_t osprocid; +#else + uint osprocid; +#endif Lock lock; _Thread *thread; _Threadlist runqueue; @@ -63,10 +74,12 @@ struct Proc Jmp sigjmp; }; -extern Proc *xxx; #define proc() _threadproc() #define setproc(p) _threadsetproc(p) +extern Proc *_threadprocs; +extern Lock _threadprocslock; + extern void _procstart(Proc*, void (*fn)(Proc*)); extern _Thread *_threadcreate(Proc*, void(*fn)(void*), void*, uint); extern void _threadexit(void); |