Continue fighting pthreads.
Clean up thread library a bit too.
This commit is contained in:
parent
c6687d4591
commit
7966faa931
19 changed files with 539 additions and 654 deletions
|
|
@ -7,31 +7,28 @@
|
|||
* _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.
|
||||
* while holding p->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.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <assert.h>
|
||||
#include <lib9.h>
|
||||
#include <libc.h>
|
||||
#include <thread.h>
|
||||
#include "label.h"
|
||||
|
||||
typedef struct Thread Thread;
|
||||
typedef struct Proc Proc;
|
||||
typedef struct Proc Proc;
|
||||
typedef struct Tqueue Tqueue;
|
||||
typedef struct Pqueue Pqueue;
|
||||
typedef struct Rgrp Rgrp;
|
||||
typedef struct Execargs Execargs;
|
||||
|
||||
/* must match list in sched.c */
|
||||
typedef enum
|
||||
{
|
||||
Dead,
|
||||
|
|
@ -50,17 +47,9 @@ typedef enum
|
|||
|
||||
enum
|
||||
{
|
||||
RENDHASH = 10009,
|
||||
Printsize = 2048,
|
||||
NPRIV = 8,
|
||||
};
|
||||
|
||||
struct Rgrp
|
||||
{
|
||||
Lock lock;
|
||||
Thread *hash[RENDHASH];
|
||||
};
|
||||
|
||||
struct Tqueue /* Thread queue */
|
||||
{
|
||||
int asleep;
|
||||
|
|
@ -68,27 +57,38 @@ struct Tqueue /* Thread queue */
|
|||
Thread *tail;
|
||||
};
|
||||
|
||||
struct Pqueue { /* Proc queue */
|
||||
Lock lock;
|
||||
Proc *head;
|
||||
Proc **tail;
|
||||
};
|
||||
|
||||
struct Thread
|
||||
{
|
||||
Lock lock; /* protects thread data structure */
|
||||
Label 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 */
|
||||
int asleep; /* thread is in _threadsleep */
|
||||
Label context; /* for context switches */
|
||||
int grp; /* thread group */
|
||||
int id; /* thread id */
|
||||
int moribund; /* thread needs to die */
|
||||
char *name; /* name of thread */
|
||||
Thread *next; /* next on ready queue */
|
||||
Thread *nextt; /* next on list of threads in this proc */
|
||||
State nextstate; /* next run state */
|
||||
Proc *proc; /* proc of this thread */
|
||||
Thread *prevt; /* prev on list of threads in this proc */
|
||||
int ret; /* return value for Exec, Fork */
|
||||
State state; /* run state */
|
||||
uchar *stk; /* top of stack (lowest address of stack) */
|
||||
uint stksize; /* stack size */
|
||||
void* udata[NPRIV]; /* User per-thread data pointer */
|
||||
|
||||
char *cmdname; /* ptr to name of thread */
|
||||
/*
|
||||
* for debugging only
|
||||
* (could go away without impacting correct behavior):
|
||||
*/
|
||||
|
||||
int inrendez;
|
||||
Channel *altc;
|
||||
_Procrend altrend;
|
||||
|
||||
|
|
@ -96,10 +96,7 @@ struct Thread
|
|||
Alt *alt; /* pointer to current alt structure (debugging) */
|
||||
ulong userpc;
|
||||
Channel *c;
|
||||
pthread_cond_t cond;
|
||||
|
||||
void* udata[NPRIV]; /* User per-thread data pointer */
|
||||
int lastfd;
|
||||
};
|
||||
|
||||
struct Execargs
|
||||
|
|
@ -113,12 +110,13 @@ struct Execargs
|
|||
struct Proc
|
||||
{
|
||||
Lock lock;
|
||||
Label sched; /* for context switches */
|
||||
Proc *link; /* in proctab */
|
||||
int pid; /* process id */
|
||||
|
||||
Label context; /* for context switches */
|
||||
Proc *link; /* in ptab */
|
||||
int splhi; /* delay notes */
|
||||
Thread *thread; /* running thread */
|
||||
Thread *idle; /* idle thread */
|
||||
int id;
|
||||
|
||||
int needexec;
|
||||
Execargs exec; /* exec argument */
|
||||
|
|
@ -131,13 +129,15 @@ struct 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 (*schedfn)(Proc*); /* function to call in scheduler */
|
||||
|
||||
_Procrend rend; /* sleep here for more ready threads */
|
||||
|
||||
void *arg; /* passed between shared and unshared stk */
|
||||
|
|
@ -147,29 +147,17 @@ struct Proc
|
|||
|
||||
void* udata; /* User per-proc data pointer */
|
||||
int nsched;
|
||||
};
|
||||
|
||||
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;
|
||||
/*
|
||||
* for debugging only
|
||||
*/
|
||||
int pid; /* process id */
|
||||
int pthreadid; /* pthread id */
|
||||
};
|
||||
|
||||
void _swaplabel(Label*, Label*);
|
||||
void _freeproc(Proc*);
|
||||
Proc* _newproc(void(*)(void*), void*, uint, char*, int, int);
|
||||
Proc* _newproc(void);
|
||||
int _newthread(Proc*, void(*)(void*), void*, uint, char*, int);
|
||||
int _procsplhi(void);
|
||||
void _procsplx(int);
|
||||
int _sched(void);
|
||||
|
|
@ -177,7 +165,8 @@ int _schedexec(Execargs*);
|
|||
void _schedexecwait(void);
|
||||
void _schedexit(Proc*);
|
||||
int _schedfork(Proc*);
|
||||
void _scheduler(void*);
|
||||
void _threadfree(Thread*);
|
||||
void _threadscheduler(void*);
|
||||
void _systhreadinit(void);
|
||||
void _threadassert(char*);
|
||||
void __threaddebug(ulong, char*, ...);
|
||||
|
|
@ -186,12 +175,15 @@ void _threadexitsall(char*);
|
|||
Proc* _threadgetproc(void);
|
||||
extern void _threadmultiproc(void);
|
||||
Proc* _threaddelproc(void);
|
||||
void _threadinitproc(Proc*);
|
||||
void _threadwaitkids(Proc*);
|
||||
void _threadsetproc(Proc*);
|
||||
void _threadinitstack(Thread*, void(*)(void*), void*);
|
||||
void _threadlinkmain(void);
|
||||
void* _threadmalloc(long, int);
|
||||
void _threadnote(void*, char*);
|
||||
void _threadready(Thread*);
|
||||
void _threadidle(void);
|
||||
void _threadsetidle(int);
|
||||
void _threadsleep(_Procrend*);
|
||||
void _threadwakeup(_Procrend*);
|
||||
void _threadsignal(void);
|
||||
|
|
@ -200,13 +192,15 @@ long _xdec(long*);
|
|||
void _xinc(long*);
|
||||
void _threadremove(Proc*, Thread*);
|
||||
void threadstatus(void);
|
||||
void _threadstartproc(Proc*);
|
||||
void _threadexitproc(char*);
|
||||
void _threadexitallproc(char*);
|
||||
|
||||
extern int _threadnprocs;
|
||||
extern int _threaddebuglevel;
|
||||
extern char* _threadexitsallstatus;
|
||||
extern Pqueue _threadpq;
|
||||
extern Channel* _threadwaitchan;
|
||||
extern Rgrp _threadrgrp;
|
||||
extern void _stackfree(void*);
|
||||
|
||||
#define DBGAPPL (1 << 0)
|
||||
#define DBGSCHED (1 << 16)
|
||||
|
|
@ -216,8 +210,6 @@ extern void _stackfree(void*);
|
|||
#define DBGNOTE (1 << 20)
|
||||
#define DBGEXEC (1 << 21)
|
||||
|
||||
#define ioproc_arg(io, type) (va_arg((io)->arg, type))
|
||||
extern int _threadgetpid(void);
|
||||
extern void _threadmemset(void*, int, int);
|
||||
extern void _threaddebugmemset(void*, int, int);
|
||||
extern int _threadprocs;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue