diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libthread/threadimpl.h |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libthread/threadimpl.h')
-rwxr-xr-x | sys/src/libthread/threadimpl.h | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/sys/src/libthread/threadimpl.h b/sys/src/libthread/threadimpl.h new file mode 100755 index 000000000..c5f7c0f2e --- /dev/null +++ b/sys/src/libthread/threadimpl.h @@ -0,0 +1,198 @@ +/* + * Some notes on locking: + * + * All the locking woes come from implementing + * threadinterrupt (and threadkill). + * + * _threadgetproc()->thread is always a live pointer. + * p->threads, p->ready, and _threadrgrp also contain + * live thread pointers. These may only be consulted + * while holding p->lock or _threadrgrp.lock; in procs + * other than p, the pointers are only guaranteed to be live + * while the lock is still being held. + * + * Thread structures can only be freed by the proc + * they belong to. Threads marked with t->inrendez + * need to be extracted from the _threadrgrp before + * being freed. + * + * _threadrgrp.lock cannot be acquired while holding p->lock. + */ + +typedef struct Pqueue Pqueue; +typedef struct Rgrp Rgrp; +typedef struct Tqueue Tqueue; +typedef struct Thread Thread; +typedef struct Execargs Execargs; +typedef struct Proc Proc; + +/* must match list in sched.c */ +typedef enum +{ + Dead, + Running, + Ready, + Rendezvous, +} State; + +typedef enum +{ + Channone, + Chanalt, + Chansend, + Chanrecv, +} Chanstate; + +enum +{ + RENDHASH = 13, + Printsize = 2048, + NPRIV = 8, +}; + +struct Rgrp +{ + Lock lock; + Thread *hash[RENDHASH]; +}; + +struct Tqueue /* Thread queue */ +{ + int asleep; + Thread *head; + Thread **tail; +}; + +struct Thread +{ + Lock lock; /* protects thread data structure */ + jmp_buf sched; /* for context switches */ + int id; /* thread id */ + int grp; /* thread group */ + int moribund; /* thread needs to die */ + State state; /* run state */ + State nextstate; /* next run state */ + uchar *stk; /* top of stack (lowest address of stack) */ + uint stksize; /* stack size */ + Thread *next; /* next on ready queue */ + + Proc *proc; /* proc of this thread */ + Thread *nextt; /* next on list of threads in this proc*/ + int ret; /* return value for Exec, Fork */ + + char *cmdname; /* ptr to name of thread */ + + int inrendez; + Thread *rendhash; /* Trgrp linked list */ + void* rendtag; /* rendezvous tag */ + void* rendval; /* rendezvous value */ + int rendbreak; /* rendezvous has been taken */ + + Chanstate chan; /* which channel operation is current */ + Alt *alt; /* pointer to current alt structure (debugging) */ + + void* udata[NPRIV]; /* User per-thread data pointer */ +}; + +struct Execargs +{ + char *prog; + char **args; + int fd[2]; +}; + +struct Proc +{ + Lock lock; + jmp_buf sched; /* for context switches */ + int pid; /* process id */ + int splhi; /* delay notes */ + Thread *thread; /* running thread */ + + int needexec; + Execargs exec; /* exec argument */ + Proc *newproc; /* fork argument */ + char exitstr[ERRMAX]; /* exit status */ + + int rforkflag; + int nthreads; + Tqueue threads; /* All threads of this proc */ + Tqueue ready; /* Runnable threads */ + Lock readylock; + + char printbuf[Printsize]; + int blocked; /* In a rendezvous */ + int pending; /* delayed note pending */ + int nonotes; /* delay notes */ + uint nextID; /* ID of most recently created thread */ + Proc *next; /* linked list of Procs */ + + void *arg; /* passed between shared and unshared stk */ + char str[ERRMAX]; /* used by threadexits to avoid malloc */ + + void* wdata; /* Lib(worker) per-proc data pointer */ + void* udata; /* User per-proc data pointer */ + char threadint; /* tag for threadexitsall() */ +}; + +struct Pqueue { /* Proc queue */ + Lock lock; + Proc *head; + Proc **tail; +}; + +struct Ioproc +{ + int tid; + Channel *c, *creply; + int inuse; + long (*op)(va_list*); + va_list arg; + long ret; + char err[ERRMAX]; + Ioproc *next; +}; + +void _freeproc(Proc*); +void _freethread(Thread*); +Proc* _newproc(void(*)(void*), void*, uint, char*, int, int); +int _procsplhi(void); +void _procsplx(int); +void _sched(void); +int _schedexec(Execargs*); +void _schedexecwait(void); +void _schedexit(Proc*); +int _schedfork(Proc*); +void _schedinit(void*); +void _systhreadinit(void); +void _threadassert(char*); +void _threadbreakrendez(void); +void _threaddebug(ulong, char*, ...); +void _threadexitsall(char*); +void _threadflagrendez(Thread*); +Proc* _threadgetproc(void); +void _threadsetproc(Proc*); +void _threadinitstack(Thread*, void(*)(void*), void*); +void* _threadmalloc(long, int); +void _threadnote(void*, char*); +void _threadready(Thread*); +void* _threadrendezvous(void*, void*); +void _threadsignal(void); +void _threadsysfatal(char*, va_list); +void** _workerdata(void); + +extern int _threaddebuglevel; +extern char* _threadexitsallstatus; +extern Pqueue _threadpq; +extern Channel* _threadwaitchan; +extern Rgrp _threadrgrp; + +#define DBGAPPL (1 << 0) +#define DBGSCHED (1 << 16) +#define DBGCHAN (1 << 17) +#define DBGREND (1 << 18) +/* #define DBGKILL (1 << 19) */ +#define DBGNOTE (1 << 20) +#define DBGEXEC (1 << 21) + +#define ioproc_arg(io, type) (va_arg((io)->arg, type)) |