Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | /*******************************************************************\ | |
11 | * * | |
12 | * Information Technology Center * | |
13 | * Carnegie-Mellon University * | |
14 | * * | |
15 | * * | |
16 | \*******************************************************************/ | |
17 | ||
18 | #ifndef __LWP_INCLUDE_ | |
19 | #define __LWP_INCLUDE_ 1 | |
20 | ||
21 | #if !defined(KERNEL) && !defined(_KMEMUSER) | |
22 | #include <afs/param.h> | |
23 | ||
24 | /* External function declarations. */ | |
25 | #ifdef AFS_NT40_ENV | |
26 | #ifndef _MFC_VER /*skip if doing Microsoft foundation class */ | |
27 | #include <winsock2.h> | |
28 | #endif | |
29 | #elif defined(AFS_LINUX20_ENV) | |
30 | #include <unistd.h> | |
31 | #include <time.h> | |
32 | #include <sys/time.h> | |
33 | #else | |
34 | # include <unistd.h> /* select() prototype */ | |
35 | # include <sys/types.h> /* fd_set on older platforms */ | |
36 | # include <sys/time.h> /* struct timeval, select() prototype */ | |
37 | # ifndef FD_SET | |
38 | # include <sys/select.h> /* fd_set on newer platforms */ | |
39 | # endif | |
40 | #endif | |
41 | ||
42 | /* fasttime.c */ | |
43 | extern int FT_GetTimeOfDay(struct timeval *tv, struct timezone *tz); | |
44 | extern int FT_Init(int printErrors, int notReally); | |
45 | extern int FT_AGetTimeOfDay(struct timeval *tv, struct timezone *tz); | |
46 | extern unsigned int FT_ApproxTime(void); | |
47 | ||
48 | #if !defined(AFS_PTHREAD_ENV) | |
49 | # if defined(USE_UCONTEXT) && defined(HAVE_UCONTEXT_H) | |
50 | # include <ucontext.h> | |
51 | # else | |
52 | # include <setjmp.h> | |
53 | # endif | |
54 | ||
55 | #define LWP_SUCCESS 0 | |
56 | #define LWP_EBADPID -1 | |
57 | #define LWP_EBLOCKED -2 | |
58 | #define LWP_EINIT -3 | |
59 | #define LWP_EMAXPROC -4 | |
60 | #define LWP_ENOBLOCK -5 | |
61 | #define LWP_ENOMEM -6 | |
62 | #define LWP_ENOPROCESS -7 | |
63 | #define LWP_ENOWAIT -8 | |
64 | #define LWP_EBADCOUNT -9 | |
65 | #define LWP_EBADEVENT -10 | |
66 | #define LWP_EBADPRI -11 | |
67 | #define LWP_NO_STACK -12 | |
68 | /* These two are for the signal mechanism. */ | |
69 | #define LWP_EBADSIG -13 /* bad signal number */ | |
70 | #define LWP_ESYSTEM -14 /* system call failed */ | |
71 | /* These are for the rock mechanism */ | |
72 | #define LWP_ENOROCKS -15 /* all rocks are in use */ | |
73 | #define LWP_EBADROCK -16 /* the specified rock does not exist */ | |
74 | ||
75 | /* Maximum priority permissible (minimum is always 0) */ | |
76 | #define LWP_MAX_PRIORITY 4 /* changed from 1 */ | |
77 | ||
78 | /* Usual priority used by user LWPs */ | |
79 | #define LWP_NORMAL_PRIORITY (LWP_MAX_PRIORITY-2) | |
80 | ||
81 | /* Initial size of eventlist in a PCB; grows dynamically */ | |
82 | #define EVINITSIZE 5 | |
83 | ||
84 | typedef struct lwp_pcb *PROCESS; | |
85 | ||
86 | #ifdef AFS_NT40_ENV | |
87 | #include <windef.h> | |
88 | typedef struct lwp_pcb { | |
89 | char name[32]; /* name of LWP */ | |
90 | LPVOID fiber; | |
91 | int (*funP) (); /* function to execute on this LWP */ | |
92 | void *argP; /* argument for function */ | |
93 | int priority; /* LWP priority */ | |
94 | int stacksize; /* Just for reference. */ | |
95 | /* the following are used for scheduling */ | |
96 | int status:8; | |
97 | int eventlistsize:8; | |
98 | int eventcnt:8; | |
99 | int padding:8; | |
100 | void **eventlist; | |
101 | int wakevent; | |
102 | int waitcnt; | |
103 | struct lwp_pcb *next, *prev; | |
104 | struct IoRequest *iomgrRequest; | |
105 | int index; /* new number (++) for each process created. */ | |
106 | } lwp_pcb_t; | |
107 | ||
108 | #else | |
109 | struct lwp_context { /* saved context for dispatcher */ | |
110 | char *topstack; /* ptr to top of process stack */ | |
111 | #if defined(USE_UCONTEXT) && defined(HAVE_UCONTEXT_H) | |
112 | ucontext_t ucontext; | |
113 | int state; | |
114 | #else /* !HAVE_UCONTEXT_H */ | |
115 | # if defined(sparc) && !defined(__linux__) | |
116 | # ifdef save_allregs | |
117 | int globals[7 + 1 + 32 + 2 + 32 + 2]; /* g1-g7, y reg, f0-f31, fsr, fq, c0-c31, csr, cq. */ | |
118 | # else | |
119 | int globals[8]; /* g1-g7 and y registers. */ | |
120 | # endif | |
121 | # endif | |
122 | jmp_buf setjmp_buffer; | |
123 | #endif /* HAVE_UCONTEXT_H */ | |
124 | }; | |
125 | ||
126 | struct rock { /* to hide things associated with this LWP under */ | |
127 | int tag; /* unique identifier for this rock */ | |
128 | char *value; /* pointer to some arbitrary data structure */ | |
129 | }; | |
130 | ||
131 | #define MAXROCKS 4 /* max no. of rocks per LWP */ | |
132 | ||
133 | struct lwp_pcb { /* process control block */ | |
134 | char name[32]; /* ASCII name */ | |
135 | int rc; /* most recent return code */ | |
136 | char status; /* status flags */ | |
137 | char blockflag; /* if (blockflag), process blocked */ | |
138 | char eventlistsize; /* size of eventlist array */ | |
139 | char padding; /* force 32-bit alignment */ | |
140 | void **eventlist; /* ptr to array of eventids */ | |
141 | int eventcnt; /* no. of events currently in eventlist array */ | |
142 | int wakevent; /* index of eventid causing wakeup */ | |
143 | int waitcnt; /* min number of events awaited */ | |
144 | int priority; /* dispatching priority */ | |
145 | struct lwp_pcb *misc; /* for LWP internal use only */ | |
146 | char *stack; /* ptr to process stack */ | |
147 | int stacksize; /* size of stack */ | |
148 | int stackcheck; /* first word of stack for overflow checking */ | |
149 | void *(*ep)(void *); /* initial entry point */ | |
150 | char *parm; /* initial parm for process */ | |
151 | struct lwp_context | |
152 | context; /* saved context for next dispatch */ | |
153 | int lwp_rused; /* no of rocks presently in use */ | |
154 | struct rock lwp_rlist[MAXROCKS]; /* set of rocks to hide things under */ | |
155 | struct lwp_pcb *next, *prev; /* ptrs to next and previous pcb */ | |
156 | int level; /* nesting level of critical sections */ | |
157 | struct IoRequest *iomgrRequest; /* request we're waiting for */ | |
158 | int index; /* LWP index: should be small index; actually is | |
159 | * incremented on each lwp_create_process */ | |
160 | }; | |
161 | #endif /* AFS_NT40_ENV */ | |
162 | ||
163 | extern int lwp_nextindex; /* Next lwp index to assign */ | |
164 | ||
165 | ||
166 | #ifndef LWP_KERNEL | |
167 | #define LWP_ActiveProcess (lwp_cpptr+0) | |
168 | #define LWP_Index() (LWP_ActiveProcess->index) | |
169 | #define LWP_HighestIndex() (lwp_nextindex - 1) | |
170 | #ifndef AFS_SUN5_ENV /* Actual functions for solaris */ | |
171 | #define LWP_SignalProcess(event) LWP_INTERNALSIGNAL(event, 1) | |
172 | #define LWP_NoYieldSignal(event) LWP_INTERNALSIGNAL(event, 0) | |
173 | #endif | |
174 | ||
175 | extern | |
176 | #endif | |
177 | struct lwp_pcb *lwp_cpptr; /* pointer to current process pcb */ | |
178 | ||
179 | struct lwp_ctl { /* LWP control structure */ | |
180 | int processcnt; /* number of lightweight processes */ | |
181 | char *outersp; /* outermost stack pointer */ | |
182 | struct lwp_pcb *outerpid; /* process carved by Initialize */ | |
183 | struct lwp_pcb *first, last; /* ptrs to first and last pcbs */ | |
184 | #ifdef __hp9000s800 | |
185 | double dsptchstack[200]; /* stack for dispatcher use only */ | |
186 | /* force 8 byte alignment */ | |
187 | #else | |
188 | char dsptchstack[800]; /* stack for dispatcher use only */ | |
189 | #endif | |
190 | }; | |
191 | ||
192 | #ifndef LWP_KERNEL | |
193 | extern | |
194 | #endif | |
195 | char lwp_debug; /* ON = show LWP debugging trace */ | |
196 | ||
197 | /* | |
198 | * Under hpux, any stack size smaller than 16K seems prone to | |
199 | * overflow problems. | |
200 | * | |
201 | * On Solaris 2.5, gethostbyname() can use up to 21920 bytes of stack | |
202 | * space. Note: when measuring this, it is important to check the | |
203 | * amount of stack space it uses for hosts that are known as well as | |
204 | * for hosts that are unknown; the stack usage can differ between these | |
205 | * cases, and also between machines apparently running the same OS | |
206 | * version. | |
207 | */ | |
208 | /* | |
209 | * On ia64 where the ucontext is used, it can be an extra 48K | |
210 | * Need to account for this. There might be two of these on the | |
211 | * stack too. This needs to be checked. | |
212 | */ | |
213 | #if defined(USE_UCONTEXT) && defined(HAVE_UCONTEXT_H) | |
214 | #define AFS_LWP_MINSTACKSIZE (288 * 1024) | |
215 | #elif defined(AFS_LINUX22_ENV) | |
216 | #define AFS_LWP_MINSTACKSIZE (192 * 1024) | |
217 | #else | |
218 | #define AFS_LWP_MINSTACKSIZE (48 * 1024) | |
219 | #endif | |
220 | ||
221 | /* Action to take on stack overflow. */ | |
222 | #define LWP_SOQUIET 1 /* do nothing */ | |
223 | #define LWP_SOABORT 2 /* abort the program */ | |
224 | #define LWP_SOMESSAGE 3 /* print a message and be quiet */ | |
225 | extern int lwp_overflowAction; | |
226 | ||
227 | /* Tells if stack size counting is enabled. */ | |
228 | extern int lwp_stackUseEnabled; | |
229 | extern int lwp_MaxStackSeen; | |
230 | ||
231 | #ifndef AFS_AIX32_ENV | |
232 | #define LWP_CreateProcess2(a, b, c, d, e, f) \ | |
233 | LWP_CreateProcess((a), (b), (c), (d), (e), (f)) | |
234 | #endif | |
235 | ||
236 | /* iomgr.c */ | |
237 | extern fd_set *IOMGR_AllocFDSet(void); | |
238 | extern int IOMGR_Select(int nfds, fd_set * rfds, fd_set * wfds, fd_set * efds, | |
239 | struct timeval *tvp); | |
240 | extern int IOMGR_Poll(void); | |
241 | extern void IOMGR_Sleep(int seconds); | |
242 | extern int IOMGR_Cancel(PROCESS pid); | |
243 | extern int IOMGR_Initialize(void); | |
244 | extern void IOMGR_FreeFDSet(fd_set * fds); | |
245 | extern int IOMGR_SoftSig(void *(*aproc) (void *), void *arock); | |
246 | ||
247 | #ifdef AFS_NT40_ENV | |
248 | /* lwp.c */ | |
249 | extern int LWP_InitializeProcessSupport(int priority, PROCESS * pid); | |
250 | extern int LWP_CreateProcess(int (*funP) (), int stacksize, int priority, | |
251 | void *argP, char *name, PROCESS * pid); | |
252 | extern int LWP_DestroyProcess(PROCESS pid); | |
253 | extern int LWP_DispatchProcess(void); | |
254 | extern int LWP_WaitProcess(void *event); | |
255 | extern int LWP_INTERNALSIGNAL(void *event, int yield); | |
256 | extern int LWP_QWait(void); | |
257 | extern int LWP_QSignal(PROCESS pid); | |
258 | #else | |
259 | extern int LWP_CurrentProcess(PROCESS * pid); | |
260 | extern int LWP_INTERNALSIGNAL(void *event, int yield); | |
261 | extern int LWP_InitializeProcessSupport(int priority, PROCESS * pid); | |
262 | extern int LWP_CreateProcess(void *(*ep)(void *), int stacksize, int priority, | |
263 | void *parm, char *name, PROCESS * pid); | |
264 | extern int LWP_DestroyProcess(PROCESS pid); | |
265 | extern int LWP_DispatchProcess(void); | |
266 | extern int LWP_WaitProcess(void *event); | |
267 | extern PROCESS LWP_ThreadId(void); | |
268 | extern int LWP_QWait(void); | |
269 | extern int LWP_QSignal(PROCESS pid); | |
270 | #endif | |
271 | ||
272 | extern afs_int32 savecontext(void (*ep)(void), | |
273 | struct lwp_context *savearea, char *sp); | |
274 | extern void returnto(struct lwp_context *savearea); | |
275 | ||
276 | #ifdef AFS_LINUX24_ENV | |
277 | /* max time we are allowed to spend in a select call on Linux to avoid | |
278 | lost signal issues */ | |
279 | #define IOMGR_MAXWAITTIME 60 /* seconds */ | |
280 | #else | |
281 | /* max time we are allowed to spend in a select call on NT */ | |
282 | #define IOMGR_MAXWAITTIME 5 /* seconds */ | |
283 | #endif | |
284 | ||
285 | /* max time we spend on a select in a Win95 DOS box */ | |
286 | #define IOMGR_WIN95WAITTIME 5000 /* microseconds */ | |
287 | ||
288 | #endif /* !AFS_PTHREAD_ENV */ | |
289 | ||
290 | extern int LWP_WaitForKeystroke(int seconds); /* -1 => forever */ | |
291 | extern int LWP_GetResponseKey(int seconds, char *key); | |
292 | extern int LWP_GetLine(char *linebuf, int len); | |
293 | ||
294 | #endif /* !KERNEL && !_KMEMUSER */ | |
295 | #endif /* __LWP_INCLUDE_ */ |