aboutsummaryrefslogtreecommitdiff
path: root/src/libthread/pthread.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-12-25 21:56:33 +0000
committerrsc <devnull@localhost>2004-12-25 21:56:33 +0000
commit1544f90960275dc9211bde30329c3258e0e1bf38 (patch)
treef55e7a73c03aaa24daa7cc2ad02822b921c477f9 /src/libthread/pthread.c
parent7788fd54094693384ef5c92c475656dba8819feb (diff)
downloadplan9port-1544f90960275dc9211bde30329c3258e0e1bf38.tar.gz
plan9port-1544f90960275dc9211bde30329c3258e0e1bf38.tar.bz2
plan9port-1544f90960275dc9211bde30329c3258e0e1bf38.zip
New thread library
Diffstat (limited to 'src/libthread/pthread.c')
-rw-r--r--src/libthread/pthread.c271
1 files changed, 0 insertions, 271 deletions
diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c
deleted file mode 100644
index 83d8b023..00000000
--- a/src/libthread/pthread.c
+++ /dev/null
@@ -1,271 +0,0 @@
-#include <u.h>
-#include <errno.h>
-#include "threadimpl.h"
-
-/*
- * Basic kernel thread management.
- */
-static pthread_key_t key;
-
-void
-_kthreadinit(void)
-{
- pthread_key_create(&key, 0);
-}
-
-void
-_kthreadsetproc(Proc *p)
-{
- sigset_t all;
-
- p->pthreadid = pthread_self();
- sigfillset(&all);
- pthread_sigmask(SIG_SETMASK, &all, nil);
- pthread_setspecific(key, p);
-}
-
-Proc*
-_kthreadgetproc(void)
-{
- return pthread_getspecific(key);
-}
-
-void
-_kthreadstartproc(Proc *p)
-{
- Proc *np;
- pthread_t tid;
- sigset_t all;
-
- np = p->newproc;
- sigfillset(&all);
- pthread_sigmask(SIG_SETMASK, &all, nil);
- if(pthread_create(&tid, nil, (void*(*)(void*))_threadscheduler,
- np) < 0)
- sysfatal("pthread_create: %r");
- np->pthreadid = tid;
-}
-
-void
-_kthreadexitproc(char *exitstr)
-{
- _threaddebug(DBGSCHED, "_pthreadexit");
- pthread_exit(nil);
-}
-
-void
-_kthreadexitallproc(char *exitstr)
-{
- _threaddebug(DBGSCHED, "_threadexitallproc");
- exits(exitstr);
-}
-
-/*
- * Exec. Pthreads does the hard work of making it possible
- * for any thread to do the waiting, so this is pretty easy.
- * We create a separate proc whose job is to wait for children
- * and deliver wait messages.
- */
-static Channel *_threadexecwaitchan;
-
-static void
-_threadwaitproc(void *v)
-{
- Channel *c;
- Waitmsg *w;
-
- _threadinternalproc();
-
- USED(v);
-
- for(;;){
- w = wait();
- if(w == nil){
- if(errno == ECHILD) /* wait for more */
- recvul(_threadexecwaitchan);
- continue;
- }
- if((c = _threadwaitchan) != nil)
- sendp(c, w);
- else
- free(w);
- }
- fprint(2, "_threadwaitproc exits\n"); /* not reached */
-}
-
-
-/*
- * Call _threadexec in the right conditions.
- */
-int
-_kthreadexec(Channel *c, int fd[3], char *prog, char *args[], int freeargs)
-{
- static Lock lk;
- int rv;
-
- if(!_threadexecwaitchan){
- lock(&lk);
- if(!_threadexecwaitchan){
- _threadexecwaitchan = chancreate(sizeof(ulong), 1);
- proccreate(_threadwaitproc, nil, 32*1024);
- }
- unlock(&lk);
- }
- rv = _threadexec(c, fd, prog, args, freeargs);
- nbsendul(_threadexecwaitchan, 1);
- return rv;
-}
-
-/*
- * Some threaded applications want to run in the background.
- * Calling fork() and exiting in the parent will result in a child
- * with a single pthread (if we are using pthreads), and will screw
- * up our internal process info if we are using clone/rfork.
- * Instead, apps should call threadbackground(), which takes
- * care of this.
- *
- * _threadbackgroundinit is called from main.
- */
-
-static int mainpid, passerpid;
-
-static void
-passer(void *x, char *msg)
-{
- Waitmsg *w;
-
- USED(x);
- if(strcmp(msg, "sys: usr2") == 0)
- _exit(0); /* daemonize */
- else if(strcmp(msg, "sys: child") == 0){
- /* child exited => so should we */
- w = wait();
- if(w == nil)
- _exit(1);
- _exit(atoi(w->msg));
- }else
- postnote(PNGROUP, mainpid, msg);
-}
-
-void
-_threadbackgroundinit(void)
-{
- int pid;
- sigset_t mask;
-
- sigfillset(&mask);
- pthread_sigmask(SIG_BLOCK, &mask, 0);
-
-return;
-
- passerpid = getpid();
- switch(pid = fork()){
- case -1:
- sysfatal("fork: %r");
-
- case 0:
- rfork(RFNOTEG);
- return;
-
- default:
- break;
- }
-
- mainpid = pid;
- notify(passer);
- notifyon("sys: child");
- notifyon("sys: usr2"); /* should already be on */
- for(;;)
- pause();
- _exit(0);
-}
-
-void
-threadbackground(void)
-{
- if(passerpid <= 1)
- return;
- postnote(PNPROC, passerpid, "sys: usr2");
-}
-
-/*
- * Notes.
- */
-Channel *_threadnotechan;
-static ulong sigs;
-static Lock _threadnotelk;
-static void _threadnoteproc(void*);
-extern int _p9strsig(char*);
-extern char *_p9sigstr(int);
-
-Channel*
-threadnotechan(void)
-{
- if(_threadnotechan == nil){
- lock(&_threadnotelk);
- if(_threadnotechan == nil){
- _threadnotechan = chancreate(sizeof(char*), 1);
- proccreate(_threadnoteproc, nil, 32*1024);
- }
- unlock(&_threadnotelk);
- }
- return _threadnotechan;
-}
-
-void
-_threadnote(void *x, char *msg)
-{
- USED(x);
-
- if(_threadexitsallstatus)
- _kthreadexitproc(_threadexitsallstatus);
-
- if(strcmp(msg, "sys: usr2") == 0)
- noted(NCONT);
-
- if(_threadnotechan == nil)
- noted(NDFLT);
-
- sigs |= 1<<_p9strsig(msg);
- noted(NCONT);
-}
-
-void
-_threadnoteproc(void *x)
-{
- int i;
- sigset_t none;
- Channel *c;
-
- _threadinternalproc();
- sigemptyset(&none);
- pthread_sigmask(SIG_SETMASK, &none, 0);
-
- c = _threadnotechan;
- for(;;){
- if(sigs == 0)
- pause();
- for(i=0; i<32; i++){
- if((sigs&(1<<i)) == 0)
- continue;
- sigs &= ~(1<<i);
- if(i == 0)
- continue;
- sendp(c, _p9sigstr(i));
- }
- }
-}
-
-void
-_threadschednote(void)
-{
-}
-
-void
-_kmaininit(void)
-{
- sigset_t all;
-
- sigfillset(&all);
- pthread_sigmask(SIG_SETMASK, &all, 0);
-}