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 /*******************************************************************\
12 * Information Technology Center *
13 * Carnegie-Mellon University *
16 \*******************************************************************/
18 #ifndef __LWP_INCLUDE_
19 #define __LWP_INCLUDE_ 1
21 #if !defined(KERNEL) && !defined(_KMEMUSER)
22 #include <afs/param.h>
24 /* External function declarations. */
26 #ifndef _MFC_VER /*skip if doing Microsoft foundation class */
29 #elif defined(AFS_LINUX20_ENV)
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 */
38 # include <sys/select.h> /* fd_set on newer platforms */
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);
48 #if !defined(AFS_PTHREAD_ENV)
49 # if defined(USE_UCONTEXT) && defined(HAVE_UCONTEXT_H)
50 # include <ucontext.h>
56 #define LWP_EBADPID -1
57 #define LWP_EBLOCKED -2
59 #define LWP_EMAXPROC -4
60 #define LWP_ENOBLOCK -5
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 */
75 /* Maximum priority permissible (minimum is always 0) */
76 #define LWP_MAX_PRIORITY 4 /* changed from 1 */
78 /* Usual priority used by user LWPs */
79 #define LWP_NORMAL_PRIORITY (LWP_MAX_PRIORITY-2)
81 /* Initial size of eventlist in a PCB; grows dynamically */
84 typedef struct lwp_pcb
*PROCESS
;
88 typedef struct lwp_pcb
{
89 char name
[32]; /* name of LWP */
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 */
103 struct lwp_pcb
*next
, *prev
;
104 struct IoRequest
*iomgrRequest
;
105 int index
; /* new number (++) for each process created. */
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)
114 #else /* !HAVE_UCONTEXT_H */
115 # if defined(sparc) && !defined(__linux__)
117 int globals
[7 + 1 + 32 + 2 + 32 + 2]; /* g1-g7, y reg, f0-f31, fsr, fq, c0-c31, csr, cq. */
119 int globals
[8]; /* g1-g7 and y registers. */
122 jmp_buf setjmp_buffer
;
123 #endif /* HAVE_UCONTEXT_H */
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 */
131 #define MAXROCKS 4 /* max no. of rocks per LWP */
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 */
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 */
161 #endif /* AFS_NT40_ENV */
163 extern int lwp_nextindex
; /* Next lwp index to assign */
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)
177 struct lwp_pcb
*lwp_cpptr
; /* pointer to current process pcb */
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 */
185 double dsptchstack
[200]; /* stack for dispatcher use only */
186 /* force 8 byte alignment */
188 char dsptchstack
[800]; /* stack for dispatcher use only */
195 char lwp_debug
; /* ON = show LWP debugging trace */
198 * Under hpux, any stack size smaller than 16K seems prone to
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
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.
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)
218 #define AFS_LWP_MINSTACKSIZE (48 * 1024)
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
;
227 /* Tells if stack size counting is enabled. */
228 extern int lwp_stackUseEnabled
;
229 extern int lwp_MaxStackSeen
;
231 #ifndef AFS_AIX32_ENV
232 #define LWP_CreateProcess2(a, b, c, d, e, f) \
233 LWP_CreateProcess((a), (b), (c), (d), (e), (f))
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
);
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
);
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
);
272 extern afs_int32
savecontext(void (*ep
)(void),
273 struct lwp_context
*savearea
, char *sp
);
274 extern void returnto(struct lwp_context
*savearea
);
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 */
281 /* max time we are allowed to spend in a select call on NT */
282 #define IOMGR_MAXWAITTIME 5 /* seconds */
285 /* max time we spend on a select in a Win95 DOS box */
286 #define IOMGR_WIN95WAITTIME 5000 /* microseconds */
288 #endif /* !AFS_PTHREAD_ENV */
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
);
294 #endif /* !KERNEL && !_KMEMUSER */
295 #endif /* __LWP_INCLUDE_ */