]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libthread/threadimpl.h
vmx: clean up mksegment, memset only if segment existed (devsegment clears new ones)
[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 };
52
53 struct Rgrp
54 {
55         Lock            lock;
56         Thread  *hash[RENDHASH];
57 };
58
59 struct Tqueue           /* Thread queue */
60 {
61         int             asleep;
62         Thread  *head;
63         Thread  **tail;
64 };
65
66 struct Thread
67 {
68         Lock            lock;           /* protects thread data structure */
69         jmp_buf         sched;          /* for context switches */
70         int             id;             /* thread id */
71         int             grp;            /* thread group */
72         int             moribund;       /* thread needs to die */
73         State           state;          /* run state */
74         State           nextstate;      /* next run state */
75         uchar           *stk;           /* top of stack (lowest address of stack) */
76         uint            stksize;        /* stack size */
77         Thread          *next;          /* next on ready queue */
78
79         Proc            *proc;          /* proc of this thread */
80         Thread          *nextt;         /* next on list of threads in this proc*/
81         int             ret;            /* return value for Exec, Fork */
82
83         char            *cmdname;       /* ptr to name of thread */
84
85         int             inrendez;
86         Thread          *rendhash;      /* Trgrp linked list */
87         void*           rendtag;        /* rendezvous tag */
88         void*           rendval;        /* rendezvous value */
89         int             rendbreak;      /* rendezvous has been taken */
90
91         Chanstate       chan;           /* which channel operation is current */
92         Alt             *alt;           /* pointer to current alt structure (debugging) */
93
94         void*           udata;          /* User per-thread data pointer */
95 };
96
97 struct Execargs
98 {
99         char            *prog;
100         char            **args;
101         int             fd[2];
102 };
103
104 struct Proc
105 {
106         Lock            lock;
107         jmp_buf         sched;                  /* for context switches */
108         int             pid;                    /* process id */
109         int             splhi;                  /* delay notes */
110         Thread          *thread;                /* running thread */
111
112         int             needexec;
113         Execargs        exec;                   /* exec argument */
114         Proc            *newproc;               /* fork argument */
115         char            exitstr[ERRMAX];        /* exit status */
116
117         int             rforkflag;
118         int             nthreads;
119         Tqueue          threads;                /* All threads of this proc */
120         Tqueue          ready;                  /* Runnable threads */
121         Lock            readylock;
122
123         char            printbuf[Printsize];
124         int             blocked;                /* In a rendezvous */
125         int             pending;                /* delayed note pending */
126         int             nonotes;                /*  delay notes */
127         uint            nextID;                 /* ID of most recently created thread */
128         Proc            *next;                  /* linked list of Procs */
129
130         void            *arg;                   /* passed between shared and unshared stk */
131         char            str[ERRMAX];            /* used by threadexits to avoid malloc */
132
133         void*           udata;                  /* User per-proc data pointer */
134         char            threadint;              /* tag for threadexitsall() */
135 };
136
137 struct Pqueue           /* Proc queue */
138 {
139         Lock            lock;
140         Proc            *head;
141         Proc            **tail;
142 };
143
144 struct Ioproc
145 {
146         QLock;
147         int             intr;
148         int             ctl;
149         Channel         *c, *creply;
150 };
151
152 struct Iocall
153 {
154         long            (*op)(va_list*);
155         va_list         arg;
156         long            ret;
157         char            err[ERRMAX];
158 };
159
160 Proc*   _newproc(void(*)(void*), void*, uint, char*, int, int);
161 int     _procsplhi(void);
162 void    _procsplx(int);
163 void    _sched(void);
164 int     _schedexec(Execargs*);
165 void    _schedexecwait(void);
166 void    _schedexit(Proc*);
167 int     _schedfork(Proc*);
168 void    _schedinit(void*);
169 void    _systhreadinit(void);
170 void    _threadassert(char*);
171 void    _threadbreakrendez(void);
172 void    _threaddebug(ulong, char*, ...);
173 void    _threadexitsall(char*);
174 void    _threadflagrendez(Thread*);
175 Proc*   _threadgetproc(void);
176 void    _threadsetproc(Proc*);
177 void    _threadinitstack(Thread*, void(*)(void*), void*);
178 void*   _threadmalloc(long, int);
179 void    _threadnote(void*, char*);
180 void    _threadready(Thread*);
181 void*   _threadrendezvous(void*, void*);
182 void    _threadsysfatal(char*, va_list);
183 void**  _workerdata(void);
184
185 extern int                      _threaddebuglevel;
186 extern char*            _threadexitsallstatus;
187 extern Pqueue           _threadpq;
188 extern Channel* _threadwaitchan;
189 extern Rgrp             _threadrgrp;
190
191 #define DBGAPPL (1 << 0)
192 #define DBGSCHED        (1 << 16)
193 #define DBGCHAN (1 << 17)
194 #define DBGREND (1 << 18)
195 /* #define DBGKILL      (1 << 19) */
196 #define DBGNOTE (1 << 20)
197 #define DBGEXEC (1 << 21)
198
199 #define ioproc_arg(io, type)    (va_arg((io)->arg, type))