]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libthread/threadimpl.h
kbdfs: work arround qemu
[plan9front.git] / sys / src / libthread / threadimpl.h
1 /* 
2  * Some notes on locking:
3  *
4  *      All the locking woes come from implementing
5  *      threadinterrupt (and threadkill).
6  *
7  *      _threadgetproc()->thread is always a live pointer.
8  *      p->threads, p->ready, and _threadrgrp also contain
9  *      live thread pointers.  These may only be consulted
10  *      while holding p->lock or _threadrgrp.lock; in procs
11  *      other than p, the pointers are only guaranteed to be live
12  *      while the lock is still being held.
13  *
14  *      Thread structures can only be freed by the proc
15  *      they belong to.  Threads marked with t->inrendez
16  *      need to be extracted from the _threadrgrp before
17  *      being freed.
18  *
19  *      _threadrgrp.lock cannot be acquired while holding p->lock.
20  */
21
22 typedef struct Pqueue   Pqueue;
23 typedef struct Rgrp             Rgrp;
24 typedef struct Tqueue   Tqueue;
25 typedef struct Thread   Thread;
26 typedef struct Execargs Execargs;
27 typedef struct Proc             Proc;
28 typedef struct Iocall   Iocall;
29
30 /* must match list in sched.c */
31 typedef enum
32 {
33         Dead,
34         Running,
35         Ready,
36         Rendezvous,
37 } State;
38         
39 typedef enum
40 {
41         Channone,
42         Chanalt,
43         Chansend,
44         Chanrecv,
45 } Chanstate;
46
47 enum
48 {
49         RENDHASH = 13,
50         Printsize = 2048,
51         NPRIV = 8,
52 };
53
54 struct Rgrp
55 {
56         Lock            lock;
57         Thread  *hash[RENDHASH];
58 };
59
60 struct Tqueue           /* Thread queue */
61 {
62         int             asleep;
63         Thread  *head;
64         Thread  **tail;
65 };
66
67 struct Thread
68 {
69         Lock            lock;           /* protects thread data structure */
70         jmp_buf         sched;          /* for context switches */
71         int             id;             /* thread id */
72         int             grp;            /* thread group */
73         int             moribund;       /* thread needs to die */
74         State           state;          /* run state */
75         State           nextstate;      /* next run state */
76         uchar           *stk;           /* top of stack (lowest address of stack) */
77         uint            stksize;        /* stack size */
78         Thread          *next;          /* next on ready queue */
79
80         Proc            *proc;          /* proc of this thread */
81         Thread          *nextt;         /* next on list of threads in this proc*/
82         int             ret;            /* return value for Exec, Fork */
83
84         char            *cmdname;       /* ptr to name of thread */
85
86         int             inrendez;
87         Thread          *rendhash;      /* Trgrp linked list */
88         void*           rendtag;        /* rendezvous tag */
89         void*           rendval;        /* rendezvous value */
90         int             rendbreak;      /* rendezvous has been taken */
91
92         Chanstate       chan;           /* which channel operation is current */
93         Alt             *alt;           /* pointer to current alt structure (debugging) */
94
95         void*   udata[NPRIV];   /* User per-thread data pointer */
96 };
97
98 struct Execargs
99 {
100         char            *prog;
101         char            **args;
102         int             fd[2];
103 };
104
105 struct Proc
106 {
107         Lock            lock;
108         jmp_buf         sched;                  /* for context switches */
109         int             pid;                    /* process id */
110         int             splhi;                  /* delay notes */
111         Thread          *thread;                /* running thread */
112
113         int             needexec;
114         Execargs        exec;                   /* exec argument */
115         Proc            *newproc;               /* fork argument */
116         char            exitstr[ERRMAX];        /* exit status */
117
118         int             rforkflag;
119         int             nthreads;
120         Tqueue          threads;                /* All threads of this proc */
121         Tqueue          ready;                  /* Runnable threads */
122         Lock            readylock;
123
124         char            printbuf[Printsize];
125         int             blocked;                /* In a rendezvous */
126         int             pending;                /* delayed note pending */
127         int             nonotes;                /*  delay notes */
128         uint            nextID;                 /* ID of most recently created thread */
129         Proc            *next;                  /* linked list of Procs */
130
131         void            *arg;                   /* passed between shared and unshared stk */
132         char            str[ERRMAX];            /* used by threadexits to avoid malloc */
133
134         void*           wdata;                  /* Lib(worker) per-proc data pointer */
135         void*           udata;                  /* User per-proc data pointer */
136         char            threadint;              /* tag for threadexitsall() */
137 };
138
139 struct Pqueue           /* Proc queue */
140 {
141         Lock            lock;
142         Proc            *head;
143         Proc            **tail;
144 };
145
146 struct Ioproc
147 {
148         QLock;
149         int             intr;
150         int             ctl;
151         Channel         *c, *creply;
152 };
153
154 struct Iocall
155 {
156         long            (*op)(va_list*);
157         va_list         arg;
158         long            ret;
159         char            err[ERRMAX];
160 };
161
162 void    _freeproc(Proc*);
163 void    _freethread(Thread*);
164 Proc*   _newproc(void(*)(void*), void*, uint, char*, int, int);
165 int     _procsplhi(void);
166 void    _procsplx(int);
167 void    _sched(void);
168 int     _schedexec(Execargs*);
169 void    _schedexecwait(void);
170 void    _schedexit(Proc*);
171 int     _schedfork(Proc*);
172 void    _schedinit(void*);
173 void    _systhreadinit(void);
174 void    _threadassert(char*);
175 void    _threadbreakrendez(void);
176 void    _threaddebug(ulong, char*, ...);
177 void    _threadexitsall(char*);
178 void    _threadflagrendez(Thread*);
179 Proc*   _threadgetproc(void);
180 void    _threadsetproc(Proc*);
181 void    _threadinitstack(Thread*, void(*)(void*), void*);
182 void*   _threadmalloc(long, int);
183 void    _threadnote(void*, char*);
184 void    _threadready(Thread*);
185 void*   _threadrendezvous(void*, void*);
186 void    _threadsignal(void);
187 void    _threadsysfatal(char*, va_list);
188 void**  _workerdata(void);
189
190 extern int                      _threaddebuglevel;
191 extern char*            _threadexitsallstatus;
192 extern Pqueue           _threadpq;
193 extern Channel* _threadwaitchan;
194 extern Rgrp             _threadrgrp;
195
196 #define DBGAPPL (1 << 0)
197 #define DBGSCHED        (1 << 16)
198 #define DBGCHAN (1 << 17)
199 #define DBGREND (1 << 18)
200 /* #define DBGKILL      (1 << 19) */
201 #define DBGNOTE (1 << 20)
202 #define DBGEXEC (1 << 21)
203
204 #define ioproc_arg(io, type)    (va_arg((io)->arg, type))