2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
12 /*******************************************************************\
14 * Information Technology Center *
15 * Carnegie-Mellon University *
18 \*******************************************************************/
20 #ifndef __LWP_INCLUDE_
21 #define __LWP_INCLUDE_ 1
23 #if !defined(KERNEL) && !defined(_KMEMUSER) && !defined(AFS_PTHREAD_ENV)
24 #include <afs/param.h>
28 #define LWP_EBADPID -1
29 #define LWP_EBLOCKED -2
31 #define LWP_EMAXPROC -4
32 #define LWP_ENOBLOCK -5
34 #define LWP_ENOPROCESS -7
35 #define LWP_ENOWAIT -8
36 #define LWP_EBADCOUNT -9
37 #define LWP_EBADEVENT -10
38 #define LWP_EBADPRI -11
39 #define LWP_NO_STACK -12
40 /* These two are for the signal mechanism. */
41 #define LWP_EBADSIG -13 /* bad signal number */
42 #define LWP_ESYSTEM -14 /* system call failed */
43 /* These are for the rock mechanism */
44 #define LWP_ENOROCKS -15 /* all rocks are in use */
45 #define LWP_EBADROCK -16 /* the specified rock does not exist */
47 #if defined(USE_PTHREADS) || defined(USE_SOLARIS_THREADS)
48 #ifdef USE_SOLARIS_THREADS
50 typedef int pthread_t;
51 typedef void *pthread_addr_t;
52 typedef void *pthread_condattr_t;
53 typedef void (*pthread_destructor_t)(void *);
54 typedef pthread_addr_t (*pthread_startroutine_t)(pthread_addr_t);
55 #define pthread_mutex_lock mutex_lock
56 #define pthread_mutex_unlock mutex_unlock
57 #define pthread_getspecific thr_getspecific
58 #define pthread_setspecific thr_setspecific
59 #define pthread_yield thr_yield
60 /*typedef mutex_t pthread_mutex_t;*/
61 typedef thread_key_t pthread_key_t;
62 typedef cond_t PTHREAD_COND, *pthread_cond_t;
64 #define PTHREAD_DEFAULT_SCHED 1
66 #define MUTEX_FAST_NP 0
67 #define PTHREAD_DEFAULT_STACK 65536 /* 64 K */
68 #define PRI_OTHER_MIN 1
69 #define PRI_OTHER_MAX 127
70 #define PRI_OTHER_MID ((PRI_OTHER_MIN + PRI_OTHER_MAX)/2)
71 #define DESTRUCTOR_TAB_CHUNK 20
72 #define maskAllSignals(o) thr_sigsetmask(SIG_BLOCK,&pthread_allSignals,&o)
73 #define restoreAllSignals(o) thr_sigsetmask(SIG_SETMASK,&o,NULL)
75 typedef struct PTHREAD_MUTEX {
80 } PTHREAD_MUTEX, *pthread_mutex_t;
83 typedef struct PTHREAD_ATTR {
86 } PTHREAD_ATTR, *pthread_attr_t;
89 void (*destructor)(void*);
94 int nentries; /* size allocated (in terms of number of slots) */
95 int next_free; /* next free slot */
97 } pthread_destructor_tab_t;
98 define DTAB_SIZE(size) (sizeof(pthread_destructor_tab_t) + (size)*sizeof(dest_slot_t))
105 #define LWP_MAX_PRIORITY 0
106 #define LWP_NORMAL_PRIORITY 0
107 #define LWP_NO_PRIORITIES
109 * We define PROCESS as a pointer to this struct, rather than simply as
110 * a pthread_t since some applications test for a process handle being
111 * non-zero. This can't be done on a pthread_t.
113 typedef struct lwp_process {
114 pthread_t handle; /* The pthreads handle */
115 struct lwp_process *next; /* Next LWP process */
116 char *name; /* LWP name of the process */
117 pthread_startroutine_t ep; /* Process entry point */
118 pthread_addr_t arg; /* Initial parameter */
122 {/* to hide things associated with this LWP under */
123 int tag; /* unique identifier for this rock */
124 char *value; /* pointer to some arbitrary data structure */
127 #define MAXROCKS 4 /* max no. of rocks per LWP */
132 /*#define CMA_DEBUG 1*/
136 #define LWP_CHECKSTUFF(msg) lwp_checkstuff(msg)
138 #define LWP_CHECKSTUFF(msg)
142 #define debugf(m) printf m
147 #define IOMGR_Poll() LWP_DispatchProcess()
150 * These two macros can be used to enter/exit the LWP context in a CMA
151 * program. They simply acquire/release the global LWP mutex .
153 extern pthread_mutex_t lwp_mutex;
154 #define LWP_EXIT_LWP_CONTEXT() pthread_mutex_unlock(&lwp_mutex)
155 #define LWP_ENTER_LWP_CONTEXT() pthread_mutex_lock(&lwp_mutex)
158 #define lwp_abort() abort()
160 /* Maximum priority permissible (minimum is always 0) */
161 #define LWP_MAX_PRIORITY 4 /* changed from 1 */
163 /* Usual priority used by user LWPs */
164 #define LWP_NORMAL_PRIORITY (LWP_MAX_PRIORITY-2)
166 /* Initial size of eventlist in a PCB; grows dynamically */
169 typedef struct lwp_pcb *PROCESS;
173 typedef struct lwp_pcb {
174 char name[32]; /* name of LWP */
176 int (*funP)(); /* function to execute on this LWP */
177 void *argP; /* argument for function */
178 int priority; /* LWP priority */
179 int stacksize; /* Just for reference. */
180 /* the following are used for scheduling */
188 struct lwp_pcb *next, *prev;
189 struct IoRequest *iomgrRequest;
190 int index; /* new number (++) for each process created. */
194 struct lwp_context { /* saved context for dispatcher */
195 char *topstack; /* ptr to top of process stack */
198 int globals[7+1+32+2+32+2]; /* g1-g7, y reg, f0-f31, fsr, fq, c0-c31, csr, cq. */
200 int globals[8]; /* g1-g7 and y registers. */
203 jmp_buf setjmp_buffer;
207 {/* to hide things associated with this LWP under */
208 int tag; /* unique identifier for this rock */
209 char *value; /* pointer to some arbitrary data structure */
212 #define MAXROCKS 4 /* max no. of rocks per LWP */
214 struct lwp_pcb { /* process control block */
215 char name[32]; /* ASCII name */
216 int rc; /* most recent return code */
217 char status; /* status flags */
218 char blockflag; /* if (blockflag), process blocked */
219 char eventlistsize; /* size of eventlist array */
220 char padding; /* force 32-bit alignment */
221 char **eventlist; /* ptr to array of eventids */
222 int eventcnt; /* no. of events currently in eventlist array*/
223 int wakevent; /* index of eventid causing wakeup */
224 int waitcnt; /* min number of events awaited */
225 int priority; /* dispatching priority */
226 struct lwp_pcb *misc; /* for LWP internal use only */
227 char *stack; /* ptr to process stack */
228 int stacksize; /* size of stack */
229 int stackcheck; /* first word of stack for overflow checking */
230 int (*ep)(); /* initial entry point */
231 char *parm; /* initial parm for process */
233 context; /* saved context for next dispatch */
234 int lwp_rused; /* no of rocks presently in use */
235 struct rock lwp_rlist[MAXROCKS]; /* set of rocks to hide things under */
236 struct lwp_pcb *next, *prev; /* ptrs to next and previous pcb */
237 int level; /* nesting level of critical sections */
238 struct IoRequest *iomgrRequest; /* request we're waiting for */
239 int index; /* LWP index: should be small index; actually is
240 incremented on each lwp_create_process */
242 #endif /* AFS_NT40_ENV */
244 extern int lwp_nextindex; /* Next lwp index to assign */
248 #define LWP_ActiveProcess (lwp_cpptr+0)
249 #define LWP_Index() (LWP_ActiveProcess->index)
250 #define LWP_HighestIndex() (lwp_nextindex - 1)
251 #ifndef AFS_SUN5_ENV /* Actual functions for solaris */
252 #define LWP_SignalProcess(event) LWP_INTERNALSIGNAL(event, 1)
253 #define LWP_NoYieldSignal(event) LWP_INTERNALSIGNAL(event, 0)
258 struct lwp_pcb *lwp_cpptr; /* pointer to current process pcb */
260 struct lwp_ctl { /* LWP control structure */
261 int processcnt; /* number of lightweight processes */
262 char *outersp; /* outermost stack pointer */
263 struct lwp_pcb *outerpid; /* process carved by Initialize */
264 struct lwp_pcb *first, last; /* ptrs to first and last pcbs */
266 double dsptchstack[200]; /* stack for dispatcher use only */
267 /* force 8 byte alignment */
269 char dsptchstack[800]; /* stack for dispatcher use only */
276 char lwp_debug; /* ON = show LWP debugging trace */
279 * Under hpux, any stack size smaller than 16K seems prone to
282 * On Solaris 2.5, gethostbyname() can use up to 21920 bytes of stack
283 * space. Note: when measuring this, it is important to check the
284 * amount of stack space it uses for hosts that are known as well as
285 * for hosts that are unknown; the stack usage can differ between these
286 * cases, and also between machines apparently running the same OS
289 #if defined(AFS_LINUX22_ENV)
290 #define AFS_LWP_MINSTACKSIZE (192 * 1024)
292 #define AFS_LWP_MINSTACKSIZE (48 * 1024)
295 /* Action to take on stack overflow. */
296 #define LWP_SOQUIET 1 /* do nothing */
297 #define LWP_SOABORT 2 /* abort the program */
298 #define LWP_SOMESSAGE 3 /* print a message and be quiet */
299 extern int lwp_overflowAction;
301 /* Tells if stack size counting is enabled. */
302 extern int lwp_stackUseEnabled;
303 extern int lwp_MaxStackSeen;
305 #ifndef AFS_AIX32_ENV
306 #define LWP_CreateProcess2(a, b, c, d, e, f) \
307 LWP_CreateProcess((a), (b), (c), (d), (e), (f))
310 /* External function declarations. */
312 #include <winsock2.h>
313 #elif defined(AFS_LINUX20_ENV)
316 #include <sys/time.h>
318 # include <unistd.h> /* select() prototype */
319 # include <sys/types.h> /* fd_set on older platforms */
320 # include <sys/time.h> /* struct timeval, select() prototype */
322 # include <sys/select.h> /* fd_set on newer platforms */
326 #endif /* USE_PTHREADS */
329 extern fd_set *IOMGR_AllocFDSet(void);
330 extern int IOMGR_Select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
331 struct timeval *tvp);
332 extern int IOMGR_Poll(void);
333 extern void IOMGR_Sleep(int seconds);
334 extern int IOMGR_Cancel(PROCESS pid);
335 extern int IOMGR_Initialize(void);
336 extern void IOMGR_FreeFDSet(fd_set * fds);
337 static void SignalTimeout(int code, struct timeval *timeout);
340 extern int FT_GetTimeOfDay(struct timeval *tv, struct timezone *tz);
341 extern int FT_Init (int printErrors, int notReally);
342 extern int FT_AGetTimeOfDay(struct timeval *tv, struct timezone *tz);
343 extern unsigned int FT_ApproxTime(void);
346 extern int LWP_WaitForKeystroke(int seconds); /* -1 => forever */
347 extern int LWP_GetResponseKey(int seconds, char *key);
348 extern int LWP_GetLine(char *linebuf, int len);
351 extern int LWP_InitializeProcessSupport(int priority, PROCESS *pid);
352 extern int LWP_CreateProcess(int (*funP)(), int stacksize, int priority,
353 void *argP, char *name, PROCESS *pid);
354 extern int LWP_DestroyProcess(PROCESS pid);
355 extern int LWP_DispatchProcess(void);
356 extern int LWP_WaitProcess(void *event);
357 extern int LWP_INTERNALSIGNAL(void *event, int yield);
358 extern int LWP_QWait(void);
359 extern int LWP_QSignal(PROCESS pid);
362 /* max time we are allowed to spend in a select call on NT */
363 #define IOMGR_MAXWAITTIME 5 /* seconds */
365 #endif /* __LWP_INCLUDE_ */
367 #endif /* !KERNEL && !_KMEMUSER */