aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libthread/mkfile4
-rw-r--r--src/libthread/pthread.c6
-rw-r--r--src/libthread/test/tprimes.c1
-rw-r--r--src/libthread/thread.c173
-rw-r--r--src/libthread/threadimpl.h17
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);