winlin

research st: refine the md.h

@@ -57,7 +57,6 @@ @@ -57,7 +57,6 @@
57 /***************************************** 57 /*****************************************
58 * Platform specifics 58 * Platform specifics
59 */ 59 */
60 -  
61 #if defined (AIX) 60 #if defined (AIX)
62 #define MD_STACK_GROWS_DOWN 61 #define MD_STACK_GROWS_DOWN
63 #define MD_USE_SYSV_ANON_MMAP 62 #define MD_USE_SYSV_ANON_MMAP
@@ -86,539 +85,518 @@ @@ -86,539 +85,518 @@
86 return (rt.tb_high * 1000000LL + rt.tb_low / 1000) 85 return (rt.tb_high * 1000000LL + rt.tb_low / 1000)
87 86
88 #elif defined (CYGWIN) 87 #elif defined (CYGWIN)
89 -#define MD_STACK_GROWS_DOWN  
90 -#define MD_USE_BSD_ANON_MMAP  
91 -#define MD_ACCEPT_NB_NOT_INHERITED  
92 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
93 -  
94 -#define MD_SETJMP(env) setjmp(env)  
95 -#define MD_LONGJMP(env, val) longjmp(env, val)  
96 -  
97 -#define MD_JB_SP 7  
98 -  
99 -#define MD_GET_SP(_t) (_t)->context[MD_JB_SP] 88 + #define MD_STACK_GROWS_DOWN
  89 + #define MD_USE_BSD_ANON_MMAP
  90 + #define MD_ACCEPT_NB_NOT_INHERITED
  91 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  92 +
  93 + #define MD_SETJMP(env) setjmp(env)
  94 + #define MD_LONGJMP(env, val) longjmp(env, val)
  95 +
  96 + #define MD_JB_SP 7
  97 +
  98 + #define MD_GET_SP(_t) (_t)->context[MD_JB_SP]
100 99
101 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
102 - ST_BEGIN_MACRO \  
103 - if (MD_SETJMP((_thread)->context)) \  
104 - _main(); \  
105 - MD_GET_SP(_thread) = (long) (_sp); \  
106 - ST_END_MACRO 100 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  101 + ST_BEGIN_MACRO \
  102 + if (MD_SETJMP((_thread)->context)) \
  103 + _main(); \
  104 + MD_GET_SP(_thread) = (long) (_sp); \
  105 + ST_END_MACRO
107 106
108 -#define MD_GET_UTIME() \  
109 - struct timeval tv; \  
110 - (void) gettimeofday(&tv, NULL); \  
111 - return (tv.tv_sec * 1000000LL + tv.tv_usec) 107 + #define MD_GET_UTIME() \
  108 + struct timeval tv; \
  109 + (void) gettimeofday(&tv, NULL); \
  110 + return (tv.tv_sec * 1000000LL + tv.tv_usec)
112 111
113 #elif defined (DARWIN) 112 #elif defined (DARWIN)
  113 + #define MD_STACK_GROWS_DOWN
  114 + #define MD_USE_BSD_ANON_MMAP
  115 + #define MD_ACCEPT_NB_INHERITED
  116 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  117 + #define MD_HAVE_SOCKLEN_T
  118 +
  119 + #define MD_SETJMP(env) _setjmp(env)
  120 + #define MD_LONGJMP(env, val) _longjmp(env, val)
  121 +
  122 + #if defined(__ppc__)
  123 + #define MD_JB_SP 0
  124 + #elif defined(__i386__)
  125 + #define MD_JB_SP 9
  126 + #elif defined(__x86_64__)
  127 + #define MD_JB_SP 4
  128 + #else
  129 + #error Unknown CPU architecture
  130 + #endif
114 131
115 -#define MD_STACK_GROWS_DOWN  
116 -#define MD_USE_BSD_ANON_MMAP  
117 -#define MD_ACCEPT_NB_INHERITED  
118 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
119 -#define MD_HAVE_SOCKLEN_T  
120 -  
121 -#define MD_SETJMP(env) _setjmp(env)  
122 -#define MD_LONGJMP(env, val) _longjmp(env, val)  
123 -  
124 -#if defined(__ppc__)  
125 -#define MD_JB_SP 0  
126 -#elif defined(__i386__)  
127 -#define MD_JB_SP 9  
128 -#elif defined(__x86_64__)  
129 -#define MD_JB_SP 4  
130 -#else  
131 -#error Unknown CPU architecture  
132 -#endif  
133 -  
134 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
135 - ST_BEGIN_MACRO \  
136 - if (MD_SETJMP((_thread)->context)) \  
137 - _main(); \  
138 - *((long *)&((_thread)->context[MD_JB_SP])) = (long) (_sp); \  
139 - ST_END_MACRO 132 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  133 + ST_BEGIN_MACRO \
  134 + if (MD_SETJMP((_thread)->context)) \
  135 + _main(); \
  136 + *((long *)&((_thread)->context[MD_JB_SP])) = (long) (_sp); \
  137 + ST_END_MACRO
140 138
141 -#define MD_GET_UTIME() \  
142 - struct timeval tv; \  
143 - (void) gettimeofday(&tv, NULL); \  
144 - return (tv.tv_sec * 1000000LL + tv.tv_usec) 139 + #define MD_GET_UTIME() \
  140 + struct timeval tv; \
  141 + (void) gettimeofday(&tv, NULL); \
  142 + return (tv.tv_sec * 1000000LL + tv.tv_usec)
145 143
146 #elif defined (FREEBSD) 144 #elif defined (FREEBSD)
  145 + #define MD_STACK_GROWS_DOWN
  146 + #define MD_USE_BSD_ANON_MMAP
  147 + #define MD_ACCEPT_NB_INHERITED
  148 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  149 +
  150 + #define MD_SETJMP(env) _setjmp(env)
  151 + #define MD_LONGJMP(env, val) _longjmp(env, val)
147 152
148 -#define MD_STACK_GROWS_DOWN  
149 -#define MD_USE_BSD_ANON_MMAP  
150 -#define MD_ACCEPT_NB_INHERITED  
151 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
152 -  
153 -#define MD_SETJMP(env) _setjmp(env)  
154 -#define MD_LONGJMP(env, val) _longjmp(env, val)  
155 -  
156 -#if defined(__i386__)  
157 -#define MD_JB_SP 2  
158 -#elif defined(__alpha__)  
159 -#define MD_JB_SP 34  
160 -#elif defined(__amd64__)  
161 -#define MD_JB_SP 2  
162 -#else  
163 -#error Unknown CPU architecture  
164 -#endif 153 + #if defined(__i386__)
  154 + #define MD_JB_SP 2
  155 + #elif defined(__alpha__)
  156 + #define MD_JB_SP 34
  157 + #elif defined(__amd64__)
  158 + #define MD_JB_SP 2
  159 + #else
  160 + #error Unknown CPU architecture
  161 + #endif
165 162
166 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
167 - ST_BEGIN_MACRO \  
168 - if (MD_SETJMP((_thread)->context)) \  
169 - _main(); \  
170 - (_thread)->context[0]._jb[MD_JB_SP] = (long) (_sp); \  
171 - ST_END_MACRO 163 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  164 + ST_BEGIN_MACRO \
  165 + if (MD_SETJMP((_thread)->context)) \
  166 + _main(); \
  167 + (_thread)->context[0]._jb[MD_JB_SP] = (long) (_sp); \
  168 + ST_END_MACRO
172 169
173 -#define MD_GET_UTIME() \  
174 - struct timeval tv; \  
175 - (void) gettimeofday(&tv, NULL); \  
176 - return (tv.tv_sec * 1000000LL + tv.tv_usec) 170 + #define MD_GET_UTIME() \
  171 + struct timeval tv; \
  172 + (void) gettimeofday(&tv, NULL); \
  173 + return (tv.tv_sec * 1000000LL + tv.tv_usec)
177 174
178 #elif defined (HPUX) 175 #elif defined (HPUX)
179 -  
180 -#define MD_STACK_GROWS_UP  
181 -#define MD_USE_BSD_ANON_MMAP  
182 -#define MD_ACCEPT_NB_INHERITED  
183 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
184 -  
185 -#define MD_SETJMP(env) _setjmp(env)  
186 -#define MD_LONGJMP(env, val) _longjmp(env, val)  
187 -  
188 -#ifndef __LP64__  
189 -/* 32-bit mode (ILP32 data model) */  
190 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
191 - ST_BEGIN_MACRO \  
192 - if (MD_SETJMP((_thread)->context)) \  
193 - _main(); \  
194 - ((long *)((_thread)->context))[1] = (long) (_sp); \  
195 - ST_END_MACRO  
196 -#else  
197 -/* 64-bit mode (LP64 data model) */  
198 -#define MD_STACK_PAD_SIZE 256  
199 -/* Last stack frame must be preserved */  
200 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
201 - ST_BEGIN_MACRO \  
202 - if (MD_SETJMP((_thread)->context)) \  
203 - _main(); \  
204 - memcpy((char *)(_sp) - MD_STACK_PAD_SIZE, \  
205 - ((char **)((_thread)->context))[1] - MD_STACK_PAD_SIZE, \  
206 - MD_STACK_PAD_SIZE); \  
207 - ((long *)((_thread)->context))[1] = (long) (_sp); \  
208 - ST_END_MACRO  
209 -#endif /* !__LP64__ */  
210 -  
211 -#define MD_GET_UTIME() \  
212 - struct timeval tv; \  
213 - (void) gettimeofday(&tv, NULL); \  
214 - return (tv.tv_sec * 1000000LL + tv.tv_usec) 176 + #define MD_STACK_GROWS_UP
  177 + #define MD_USE_BSD_ANON_MMAP
  178 + #define MD_ACCEPT_NB_INHERITED
  179 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  180 +
  181 + #define MD_SETJMP(env) _setjmp(env)
  182 + #define MD_LONGJMP(env, val) _longjmp(env, val)
  183 +
  184 + #ifndef __LP64__
  185 + /* 32-bit mode (ILP32 data model) */
  186 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  187 + ST_BEGIN_MACRO \
  188 + if (MD_SETJMP((_thread)->context)) \
  189 + _main(); \
  190 + ((long *)((_thread)->context))[1] = (long) (_sp); \
  191 + ST_END_MACRO
  192 + #else
  193 + /* 64-bit mode (LP64 data model) */
  194 + #define MD_STACK_PAD_SIZE 256
  195 + /* Last stack frame must be preserved */
  196 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  197 + ST_BEGIN_MACRO \
  198 + if (MD_SETJMP((_thread)->context)) \
  199 + _main(); \
  200 + memcpy((char *)(_sp) - MD_STACK_PAD_SIZE, \
  201 + ((char **)((_thread)->context))[1] - MD_STACK_PAD_SIZE, \
  202 + MD_STACK_PAD_SIZE); \
  203 + ((long *)((_thread)->context))[1] = (long) (_sp); \
  204 + ST_END_MACRO
  205 + #endif /* !__LP64__ */
  206 +
  207 + #define MD_GET_UTIME() \
  208 + struct timeval tv; \
  209 + (void) gettimeofday(&tv, NULL); \
  210 + return (tv.tv_sec * 1000000LL + tv.tv_usec)
215 211
216 #elif defined (IRIX) 212 #elif defined (IRIX)
  213 + #include <sys/syssgi.h>
  214 +
  215 + #define MD_STACK_GROWS_DOWN
  216 + #define MD_USE_SYSV_ANON_MMAP
  217 + #define MD_ACCEPT_NB_INHERITED
  218 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  219 +
  220 + #define MD_SETJMP(env) setjmp(env)
  221 + #define MD_LONGJMP(env, val) longjmp(env, val)
217 222
218 -#include <sys/syssgi.h>  
219 -  
220 -#define MD_STACK_GROWS_DOWN  
221 -#define MD_USE_SYSV_ANON_MMAP  
222 -#define MD_ACCEPT_NB_INHERITED  
223 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
224 -  
225 -#define MD_SETJMP(env) setjmp(env)  
226 -#define MD_LONGJMP(env, val) longjmp(env, val)  
227 -  
228 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
229 - ST_BEGIN_MACRO \  
230 - (void) MD_SETJMP((_thread)->context); \  
231 - (_thread)->context[JB_SP] = (long) (_sp); \  
232 - (_thread)->context[JB_PC] = (long) _main; \  
233 - ST_END_MACRO  
234 -  
235 -#define MD_GET_UTIME() \  
236 - static int inited = 0; \  
237 - static clockid_t clock_id = CLOCK_SGI_CYCLE; \  
238 - struct timespec ts; \  
239 - if (!inited) { \  
240 - if (syssgi(SGI_CYCLECNTR_SIZE) < 64) \  
241 - clock_id = CLOCK_REALTIME; \  
242 - inited = 1; \  
243 - } \  
244 - (void) clock_gettime(clock_id, &ts); \  
245 - return (ts.tv_sec * 1000000LL + ts.tv_nsec / 1000) 223 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  224 + ST_BEGIN_MACRO \
  225 + (void) MD_SETJMP((_thread)->context); \
  226 + (_thread)->context[JB_SP] = (long) (_sp); \
  227 + (_thread)->context[JB_PC] = (long) _main; \
  228 + ST_END_MACRO
246 229
247 -/*  
248 - * Cap the stack by zeroing out the saved return address register  
249 - * value. This allows libexc, used by SpeedShop, to know when to stop  
250 - * backtracing since it won't find main, start, or any other known  
251 - * stack root function in a state thread's stack. Without this libexc  
252 - * traces right off the stack and crashes.  
253 - * The function preamble stores ra at 8(sp), this stores zero there.  
254 - * N.B. This macro is compiler/ABI dependent. It must change if ANY more  
255 - * automatic variables are added to the _st_thread_main() routine, because  
256 - * the address where ra is stored will change.  
257 - */  
258 -#if !defined(__GNUC__) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32  
259 -#define MD_CAP_STACK(var_addr) \  
260 - (((volatile __uint64_t *)(var_addr))[1] = 0)  
261 -#endif 230 + #define MD_GET_UTIME() \
  231 + static int inited = 0; \
  232 + static clockid_t clock_id = CLOCK_SGI_CYCLE; \
  233 + struct timespec ts; \
  234 + if (!inited) { \
  235 + if (syssgi(SGI_CYCLECNTR_SIZE) < 64) \
  236 + clock_id = CLOCK_REALTIME; \
  237 + inited = 1; \
  238 + } \
  239 + (void) clock_gettime(clock_id, &ts); \
  240 + return (ts.tv_sec * 1000000LL + ts.tv_nsec / 1000)
  241 +
  242 + /*
  243 + * Cap the stack by zeroing out the saved return address register
  244 + * value. This allows libexc, used by SpeedShop, to know when to stop
  245 + * backtracing since it won't find main, start, or any other known
  246 + * stack root function in a state thread's stack. Without this libexc
  247 + * traces right off the stack and crashes.
  248 + * The function preamble stores ra at 8(sp), this stores zero there.
  249 + * N.B. This macro is compiler/ABI dependent. It must change if ANY more
  250 + * automatic variables are added to the _st_thread_main() routine, because
  251 + * the address where ra is stored will change.
  252 + */
  253 + #if !defined(__GNUC__) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32
  254 + #define MD_CAP_STACK(var_addr) \
  255 + (((volatile __uint64_t *)(var_addr))[1] = 0)
  256 + #endif
262 257
263 #elif defined (LINUX) 258 #elif defined (LINUX)
264 -  
265 -/*  
266 - * These are properties of the linux kernel and are the same on every  
267 - * flavor and architecture.  
268 - */  
269 -#define MD_USE_BSD_ANON_MMAP  
270 -#define MD_ACCEPT_NB_NOT_INHERITED  
271 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
272 -/*  
273 - * Modern GNU/Linux is Posix.1g compliant.  
274 - */  
275 -#define MD_HAVE_SOCKLEN_T  
276 -  
277 -/*  
278 - * All architectures and flavors of linux have the gettimeofday  
279 - * function but if you know of a faster way, use it.  
280 - */  
281 -#define MD_GET_UTIME() \  
282 - struct timeval tv; \  
283 - (void) gettimeofday(&tv, NULL); \  
284 - return (tv.tv_sec * 1000000LL + tv.tv_usec)  
285 -  
286 -#if defined(__ia64__)  
287 -#define MD_STACK_GROWS_DOWN  
288 -  
289 -/*  
290 - * IA-64 architecture. Besides traditional memory call stack, IA-64  
291 - * uses general register stack. Thus each thread needs a backing store  
292 - * for register stack in addition to memory stack. Standard  
293 - * setjmp()/longjmp() cannot be used for thread context switching  
294 - * because their implementation implicitly assumes that only one  
295 - * register stack exists.  
296 - */  
297 -#ifdef USE_LIBC_SETJMP  
298 -#undef USE_LIBC_SETJMP  
299 -#endif  
300 -#define MD_USE_BUILTIN_SETJMP  
301 -  
302 -#define MD_STACK_PAD_SIZE 128  
303 -/* Last register stack frame must be preserved */  
304 -#define MD_INIT_CONTEXT(_thread, _sp, _bsp, _main) \  
305 - ST_BEGIN_MACRO \  
306 - if (MD_SETJMP((_thread)->context)) \  
307 - _main(); \  
308 - memcpy((char *)(_bsp) - MD_STACK_PAD_SIZE, \  
309 - (char *)(_thread)->context[0].__jmpbuf[17] - MD_STACK_PAD_SIZE, \  
310 - MD_STACK_PAD_SIZE); \  
311 - (_thread)->context[0].__jmpbuf[0] = (long) (_sp); \  
312 - (_thread)->context[0].__jmpbuf[17] = (long) (_bsp); \  
313 - ST_END_MACRO  
314 -  
315 -#elif defined(__mips__)  
316 -#define MD_STACK_GROWS_DOWN  
317 -  
318 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
319 - ST_BEGIN_MACRO \  
320 - MD_SETJMP((_thread)->context); \  
321 - _thread->context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \  
322 - _thread->context[0].__jmpbuf[0].__sp = _sp; \  
323 - ST_END_MACRO  
324 -  
325 -#else /* Not IA-64 or mips */  
326 -  
327 -/*  
328 - * On linux, there are a few styles of jmpbuf format. These vary based  
329 - * on architecture/glibc combination.  
330 - *  
331 - * Most of the glibc based toggles were lifted from:  
332 - * mozilla/nsprpub/pr/include/md/_linux.h  
333 - */  
334 -  
335 -/*  
336 - * Starting with glibc 2.4, JB_SP definitions are not public anymore.  
337 - * They, however, can still be found in glibc source tree in  
338 - * architecture-specific "jmpbuf-offsets.h" files.  
339 - * Most importantly, the content of jmp_buf is mangled by setjmp to make  
340 - * it completely opaque (the mangling can be disabled by setting the  
341 - * LD_POINTER_GUARD environment variable before application execution).  
342 - * Therefore we will use built-in _st_md_cxt_save/_st_md_cxt_restore  
343 - * functions as a setjmp/longjmp replacement wherever they are available  
344 - * unless USE_LIBC_SETJMP is defined.  
345 - */  
346 -  
347 -#if defined(__powerpc__)  
348 -#define MD_STACK_GROWS_DOWN  
349 -  
350 -#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)  
351 -#ifndef JB_GPR1  
352 -#define JB_GPR1 0  
353 -#endif  
354 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_GPR1]  
355 -#else  
356 -/* not an error but certainly cause for caution */  
357 -#error "Untested use of old glibc on powerpc"  
358 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__misc[0]  
359 -#endif /* glibc 2.1 or later */  
360 -  
361 -#elif defined(__alpha)  
362 -#define MD_STACK_GROWS_DOWN  
363 -  
364 -#if defined(__GLIBC__) && __GLIBC__ >= 2  
365 -#ifndef JB_SP  
366 -#define JB_SP 8  
367 -#endif  
368 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]  
369 -#else  
370 -/* not an error but certainly cause for caution */  
371 -#error "Untested use of old glibc on alpha"  
372 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp  
373 -#endif  
374 -  
375 -#elif defined(__mc68000__)  
376 -#define MD_STACK_GROWS_DOWN  
377 -  
378 -/* m68k still uses old style sigjmp_buf */  
379 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp  
380 -  
381 -#elif defined(__sparc__)  
382 -#define MD_STACK_GROWS_DOWN  
383 -  
384 -#if defined(__GLIBC__) && __GLIBC__ >= 2  
385 -#ifndef JB_SP  
386 -#define JB_SP 0  
387 -#endif  
388 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]  
389 -#else  
390 -/* not an error but certainly cause for caution */  
391 -#error "Untested use of old glic on sparc -- also using odd mozilla derived __fp"  
392 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__fp  
393 -#endif  
394 -  
395 -#elif defined(__i386__)  
396 -#define MD_STACK_GROWS_DOWN  
397 -#define MD_USE_BUILTIN_SETJMP  
398 -  
399 -#if defined(__GLIBC__) && __GLIBC__ >= 2  
400 -#ifndef JB_SP  
401 -#define JB_SP 4  
402 -#endif  
403 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]  
404 -#else  
405 -/* not an error but certainly cause for caution */  
406 -#error "Untested use of old glibc on i386"  
407 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp  
408 -#endif  
409 -  
410 -#elif defined(__amd64__) || defined(__x86_64__)  
411 -#define MD_STACK_GROWS_DOWN  
412 -#define MD_USE_BUILTIN_SETJMP  
413 -  
414 -#ifndef JB_RSP  
415 -#define JB_RSP 6  
416 -#endif  
417 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_RSP]  
418 -  
419 -#elif defined(__arm__)  
420 -#define MD_STACK_GROWS_DOWN  
421 -  
422 -#if defined(__GLIBC__) && __GLIBC__ >= 2  
423 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[20]  
424 -#else  
425 -#error "ARM/Linux pre-glibc2 not supported yet"  
426 -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */  
427 -  
428 -#elif defined(__s390__)  
429 -#define MD_STACK_GROWS_DOWN  
430 -  
431 -/* There is no JB_SP in glibc at this time. (glibc 2.2.5)  
432 - */  
433 -#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__gregs[9]  
434 -  
435 -#elif defined(__hppa__)  
436 -#define MD_STACK_GROWS_UP  
437 -  
438 -/* yes, this is gross, unfortunately at the moment (2002/08/01) there is  
439 - * a bug in hppa's glibc header definition for JB_SP, so we can't  
440 - * use that...  
441 - */  
442 -#define MD_GET_SP(_t) (*(long *)(((char *)&(_t)->context[0].__jmpbuf[0]) + 76))  
443 -  
444 -#else  
445 -#error "Unknown CPU architecture"  
446 -#endif /* Cases with common MD_INIT_CONTEXT and different SP locations */  
447 -  
448 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
449 - ST_BEGIN_MACRO \  
450 - if (MD_SETJMP((_thread)->context)) \  
451 - _main(); \  
452 - MD_GET_SP(_thread) = (long) (_sp); \  
453 - ST_END_MACRO  
454 -  
455 -#endif /* Cases with different MD_INIT_CONTEXT */  
456 -  
457 -#if defined(MD_USE_BUILTIN_SETJMP) && !defined(USE_LIBC_SETJMP)  
458 -#define MD_SETJMP(env) _st_md_cxt_save(env)  
459 -#define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)  
460 -  
461 -extern int _st_md_cxt_save(jmp_buf env);  
462 -extern void _st_md_cxt_restore(jmp_buf env, int val);  
463 -#else  
464 -#define MD_SETJMP(env) setjmp(env)  
465 -#define MD_LONGJMP(env, val) longjmp(env, val)  
466 -#endif 259 + /*
  260 + * These are properties of the linux kernel and are the same on every
  261 + * flavor and architecture.
  262 + */
  263 + #define MD_USE_BSD_ANON_MMAP
  264 + #define MD_ACCEPT_NB_NOT_INHERITED
  265 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  266 + /*
  267 + * Modern GNU/Linux is Posix.1g compliant.
  268 + */
  269 + #define MD_HAVE_SOCKLEN_T
  270 +
  271 + /*
  272 + * All architectures and flavors of linux have the gettimeofday
  273 + * function but if you know of a faster way, use it.
  274 + */
  275 + #define MD_GET_UTIME() \
  276 + struct timeval tv; \
  277 + (void) gettimeofday(&tv, NULL); \
  278 + return (tv.tv_sec * 1000000LL + tv.tv_usec)
  279 +
  280 + #if defined(__ia64__)
  281 + #define MD_STACK_GROWS_DOWN
  282 +
  283 + /*
  284 + * IA-64 architecture. Besides traditional memory call stack, IA-64
  285 + * uses general register stack. Thus each thread needs a backing store
  286 + * for register stack in addition to memory stack. Standard
  287 + * setjmp()/longjmp() cannot be used for thread context switching
  288 + * because their implementation implicitly assumes that only one
  289 + * register stack exists.
  290 + */
  291 + #ifdef USE_LIBC_SETJMP
  292 + #undef USE_LIBC_SETJMP
  293 + #endif
  294 + #define MD_USE_BUILTIN_SETJMP
  295 +
  296 + #define MD_STACK_PAD_SIZE 128
  297 + /* Last register stack frame must be preserved */
  298 + #define MD_INIT_CONTEXT(_thread, _sp, _bsp, _main) \
  299 + ST_BEGIN_MACRO \
  300 + if (MD_SETJMP((_thread)->context)) \
  301 + _main(); \
  302 + memcpy((char *)(_bsp) - MD_STACK_PAD_SIZE, \
  303 + (char *)(_thread)->context[0].__jmpbuf[17] - MD_STACK_PAD_SIZE, \
  304 + MD_STACK_PAD_SIZE); \
  305 + (_thread)->context[0].__jmpbuf[0] = (long) (_sp); \
  306 + (_thread)->context[0].__jmpbuf[17] = (long) (_bsp); \
  307 + ST_END_MACRO
  308 + #elif defined(__mips__)
  309 + #define MD_STACK_GROWS_DOWN
  310 +
  311 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  312 + ST_BEGIN_MACRO \
  313 + MD_SETJMP((_thread)->context); \
  314 + _thread->context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \
  315 + _thread->context[0].__jmpbuf[0].__sp = _sp; \
  316 + ST_END_MACRO
  317 + #else /* Not IA-64 or mips */
  318 + /*
  319 + * On linux, there are a few styles of jmpbuf format. These vary based
  320 + * on architecture/glibc combination.
  321 + *
  322 + * Most of the glibc based toggles were lifted from:
  323 + * mozilla/nsprpub/pr/include/md/_linux.h
  324 + */
  325 + /*
  326 + * Starting with glibc 2.4, JB_SP definitions are not public anymore.
  327 + * They, however, can still be found in glibc source tree in
  328 + * architecture-specific "jmpbuf-offsets.h" files.
  329 + * Most importantly, the content of jmp_buf is mangled by setjmp to make
  330 + * it completely opaque (the mangling can be disabled by setting the
  331 + * LD_POINTER_GUARD environment variable before application execution).
  332 + * Therefore we will use built-in _st_md_cxt_save/_st_md_cxt_restore
  333 + * functions as a setjmp/longjmp replacement wherever they are available
  334 + * unless USE_LIBC_SETJMP is defined.
  335 + */
  336 + #if defined(__powerpc__)
  337 + #define MD_STACK_GROWS_DOWN
  338 +
  339 + #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
  340 + #ifndef JB_GPR1
  341 + #define JB_GPR1 0
  342 + #endif
  343 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_GPR1]
  344 + #else
  345 + /* not an error but certainly cause for caution */
  346 + #error "Untested use of old glibc on powerpc"
  347 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__misc[0]
  348 + #endif /* glibc 2.1 or later */
  349 + #elif defined(__alpha)
  350 + #define MD_STACK_GROWS_DOWN
  351 +
  352 + #if defined(__GLIBC__) && __GLIBC__ >= 2
  353 + #ifndef JB_SP
  354 + #define JB_SP 8
  355 + #endif
  356 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]
  357 + #else
  358 + /* not an error but certainly cause for caution */
  359 + #error "Untested use of old glibc on alpha"
  360 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp
  361 + #endif
  362 + #elif defined(__mc68000__)
  363 + #define MD_STACK_GROWS_DOWN
  364 +
  365 + /* m68k still uses old style sigjmp_buf */
  366 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp
  367 + #elif defined(__sparc__)
  368 + #define MD_STACK_GROWS_DOWN
  369 +
  370 + #if defined(__GLIBC__) && __GLIBC__ >= 2
  371 + #ifndef JB_SP
  372 + #define JB_SP 0
  373 + #endif
  374 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]
  375 + #else
  376 + /* not an error but certainly cause for caution */
  377 + #error "Untested use of old glic on sparc -- also using odd mozilla derived __fp"
  378 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__fp
  379 + #endif
  380 + #elif defined(__i386__)
  381 + #define MD_STACK_GROWS_DOWN
  382 + #define MD_USE_BUILTIN_SETJMP
  383 +
  384 + #if defined(__GLIBC__) && __GLIBC__ >= 2
  385 + #ifndef JB_SP
  386 + #define JB_SP 4
  387 + #endif
  388 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]
  389 + #else
  390 + /* not an error but certainly cause for caution */
  391 + #error "Untested use of old glibc on i386"
  392 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp
  393 + #endif
  394 + #elif defined(__amd64__) || defined(__x86_64__)
  395 + #define MD_STACK_GROWS_DOWN
  396 + #define MD_USE_BUILTIN_SETJMP
  397 +
  398 + #ifndef JB_RSP
  399 + #define JB_RSP 6
  400 + #endif
  401 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_RSP]
  402 + #elif defined(__arm__)
  403 + #define MD_STACK_GROWS_DOWN
  404 +
  405 + #if defined(__GLIBC__) && __GLIBC__ >= 2
  406 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[8]
  407 + #else
  408 + #error "ARM/Linux pre-glibc2 not supported yet"
  409 + #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
  410 + #elif defined(__s390__)
  411 + #define MD_STACK_GROWS_DOWN
  412 +
  413 + /* There is no JB_SP in glibc at this time. (glibc 2.2.5)
  414 + */
  415 + #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__gregs[9]
  416 + #elif defined(__hppa__)
  417 + #define MD_STACK_GROWS_UP
  418 +
  419 + /* yes, this is gross, unfortunately at the moment (2002/08/01) there is
  420 + * a bug in hppa's glibc header definition for JB_SP, so we can't
  421 + * use that...
  422 + */
  423 + #define MD_GET_SP(_t) (*(long *)(((char *)&(_t)->context[0].__jmpbuf[0]) + 76))
  424 + #else
  425 + #error "Unknown CPU architecture"
  426 + #endif /* Cases with common MD_INIT_CONTEXT and different SP locations */
  427 +
  428 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  429 + ST_BEGIN_MACRO \
  430 + if (MD_SETJMP((_thread)->context)) \
  431 + _main(); \
  432 + MD_GET_SP(_thread) = (long) (_sp); \
  433 + ST_END_MACRO
  434 + #endif /* Cases with different MD_INIT_CONTEXT */
  435 +
  436 + #if defined(MD_USE_BUILTIN_SETJMP) && !defined(USE_LIBC_SETJMP)
  437 + #define MD_SETJMP(env) _st_md_cxt_save(env)
  438 + #define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)
  439 +
  440 + extern int _st_md_cxt_save(jmp_buf env);
  441 + extern void _st_md_cxt_restore(jmp_buf env, int val);
  442 + #else
  443 + #define MD_SETJMP(env) setjmp(env)
  444 + #define MD_LONGJMP(env, val) longjmp(env, val)
  445 + #endif
467 446
468 #elif defined (NETBSD) 447 #elif defined (NETBSD)
469 -  
470 -#define MD_STACK_GROWS_DOWN  
471 -#define MD_USE_BSD_ANON_MMAP  
472 -#define MD_ACCEPT_NB_INHERITED  
473 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
474 -#define MD_HAVE_SOCKLEN_T  
475 -  
476 -#define MD_SETJMP(env) _setjmp(env)  
477 -#define MD_LONGJMP(env, val) _longjmp(env, val)  
478 -  
479 -#if defined(__i386__)  
480 -#define MD_JB_SP 2  
481 -#elif defined(__alpha__)  
482 -#define MD_JB_SP 34  
483 -#elif defined(__sparc__)  
484 -#define MD_JB_SP 0  
485 -#elif defined(__vax__)  
486 -#define MD_JB_SP 2  
487 -#else  
488 -#error Unknown CPU architecture  
489 -#endif  
490 -  
491 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
492 - ST_BEGIN_MACRO \  
493 - if (MD_SETJMP((_thread)->context)) \  
494 - _main(); \  
495 - (_thread)->context[MD_JB_SP] = (long) (_sp); \  
496 - ST_END_MACRO  
497 -  
498 -#define MD_GET_UTIME() \  
499 - struct timeval tv; \  
500 - (void) gettimeofday(&tv, NULL); \  
501 - return (tv.tv_sec * 1000000LL + tv.tv_usec) 448 + #define MD_STACK_GROWS_DOWN
  449 + #define MD_USE_BSD_ANON_MMAP
  450 + #define MD_ACCEPT_NB_INHERITED
  451 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  452 + #define MD_HAVE_SOCKLEN_T
  453 +
  454 + #define MD_SETJMP(env) _setjmp(env)
  455 + #define MD_LONGJMP(env, val) _longjmp(env, val)
  456 +
  457 + #if defined(__i386__)
  458 + #define MD_JB_SP 2
  459 + #elif defined(__alpha__)
  460 + #define MD_JB_SP 34
  461 + #elif defined(__sparc__)
  462 + #define MD_JB_SP 0
  463 + #elif defined(__vax__)
  464 + #define MD_JB_SP 2
  465 + #else
  466 + #error Unknown CPU architecture
  467 + #endif
  468 +
  469 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  470 + ST_BEGIN_MACRO \
  471 + if (MD_SETJMP((_thread)->context)) \
  472 + _main(); \
  473 + (_thread)->context[MD_JB_SP] = (long) (_sp); \
  474 + ST_END_MACRO
  475 +
  476 + #define MD_GET_UTIME() \
  477 + struct timeval tv; \
  478 + (void) gettimeofday(&tv, NULL); \
  479 + return (tv.tv_sec * 1000000LL + tv.tv_usec)
502 480
503 #elif defined (OPENBSD) 481 #elif defined (OPENBSD)
504 -  
505 -#define MD_STACK_GROWS_DOWN  
506 -#define MD_USE_BSD_ANON_MMAP  
507 -#define MD_ACCEPT_NB_INHERITED  
508 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
509 -  
510 -#define MD_SETJMP(env) _setjmp(env)  
511 -#define MD_LONGJMP(env, val) _longjmp(env, val)  
512 -  
513 -#if defined(__i386__)  
514 -#define MD_JB_SP 2  
515 -#elif defined(__alpha__)  
516 -#define MD_JB_SP 34  
517 -#elif defined(__sparc__)  
518 -#define MD_JB_SP 0  
519 -#elif defined(__amd64__)  
520 -#define MD_JB_SP 6  
521 -#else  
522 -#error Unknown CPU architecture  
523 -#endif  
524 -  
525 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
526 - ST_BEGIN_MACRO \  
527 - if (MD_SETJMP((_thread)->context)) \  
528 - _main(); \  
529 - (_thread)->context[MD_JB_SP] = (long) (_sp); \  
530 - ST_END_MACRO  
531 -  
532 -#define MD_GET_UTIME() \  
533 - struct timeval tv; \  
534 - (void) gettimeofday(&tv, NULL); \  
535 - return (tv.tv_sec * 1000000LL + tv.tv_usec) 482 + #define MD_STACK_GROWS_DOWN
  483 + #define MD_USE_BSD_ANON_MMAP
  484 + #define MD_ACCEPT_NB_INHERITED
  485 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  486 +
  487 + #define MD_SETJMP(env) _setjmp(env)
  488 + #define MD_LONGJMP(env, val) _longjmp(env, val)
  489 +
  490 + #if defined(__i386__)
  491 + #define MD_JB_SP 2
  492 + #elif defined(__alpha__)
  493 + #define MD_JB_SP 34
  494 + #elif defined(__sparc__)
  495 + #define MD_JB_SP 0
  496 + #elif defined(__amd64__)
  497 + #define MD_JB_SP 6
  498 + #else
  499 + #error Unknown CPU architecture
  500 + #endif
  501 +
  502 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  503 + ST_BEGIN_MACRO \
  504 + if (MD_SETJMP((_thread)->context)) \
  505 + _main(); \
  506 + (_thread)->context[MD_JB_SP] = (long) (_sp); \
  507 + ST_END_MACRO
  508 +
  509 + #define MD_GET_UTIME() \
  510 + struct timeval tv; \
  511 + (void) gettimeofday(&tv, NULL); \
  512 + return (tv.tv_sec * 1000000LL + tv.tv_usec)
536 513
537 #elif defined (OSF1) 514 #elif defined (OSF1)
538 -  
539 -#include <signal.h>  
540 -  
541 -#define MD_STACK_GROWS_DOWN  
542 -#define MD_USE_SYSV_ANON_MMAP  
543 -#define MD_ACCEPT_NB_NOT_INHERITED  
544 -#define MD_ALWAYS_UNSERIALIZED_ACCEPT  
545 -  
546 -#define MD_SETJMP(env) _setjmp(env)  
547 -#define MD_LONGJMP(env, val) _longjmp(env, val)  
548 -  
549 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
550 - ST_BEGIN_MACRO \  
551 - if (MD_SETJMP((_thread)->context)) \  
552 - _main(); \  
553 - ((struct sigcontext *)((_thread)->context))->sc_sp = (long) (_sp); \  
554 - ST_END_MACRO  
555 -  
556 -#define MD_GET_UTIME() \  
557 - struct timeval tv; \  
558 - (void) gettimeofday(&tv, NULL); \  
559 - return (tv.tv_sec * 1000000LL + tv.tv_usec) 515 + #include <signal.h>
  516 +
  517 + #define MD_STACK_GROWS_DOWN
  518 + #define MD_USE_SYSV_ANON_MMAP
  519 + #define MD_ACCEPT_NB_NOT_INHERITED
  520 + #define MD_ALWAYS_UNSERIALIZED_ACCEPT
  521 +
  522 + #define MD_SETJMP(env) _setjmp(env)
  523 + #define MD_LONGJMP(env, val) _longjmp(env, val)
  524 +
  525 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  526 + ST_BEGIN_MACRO \
  527 + if (MD_SETJMP((_thread)->context)) \
  528 + _main(); \
  529 + ((struct sigcontext *)((_thread)->context))->sc_sp = (long) (_sp); \
  530 + ST_END_MACRO
  531 +
  532 + #define MD_GET_UTIME() \
  533 + struct timeval tv; \
  534 + (void) gettimeofday(&tv, NULL); \
  535 + return (tv.tv_sec * 1000000LL + tv.tv_usec)
560 536
561 #elif defined (SOLARIS) 537 #elif defined (SOLARIS)
562 -  
563 -#include <sys/filio.h>  
564 -extern int getpagesize(void);  
565 -  
566 -#define MD_STACK_GROWS_DOWN  
567 -#define MD_USE_SYSV_ANON_MMAP  
568 -#define MD_ACCEPT_NB_NOT_INHERITED  
569 -  
570 -#define MD_SETJMP(env) setjmp(env)  
571 -#define MD_LONGJMP(env, val) longjmp(env, val)  
572 -  
573 -#if defined(sparc) || defined(__sparc)  
574 -#ifdef _LP64  
575 -#define MD_STACK_PAD_SIZE 4095  
576 -#endif  
577 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
578 - ST_BEGIN_MACRO \  
579 - (void) MD_SETJMP((_thread)->context); \  
580 - (_thread)->context[1] = (long) (_sp); \  
581 - (_thread)->context[2] = (long) _main; \  
582 - ST_END_MACRO  
583 -#elif defined(i386) || defined(__i386)  
584 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
585 - ST_BEGIN_MACRO \  
586 - (void) MD_SETJMP((_thread)->context); \  
587 - (_thread)->context[4] = (long) (_sp); \  
588 - (_thread)->context[5] = (long) _main; \  
589 - ST_END_MACRO  
590 -#elif defined(__amd64__)  
591 -#define MD_INIT_CONTEXT(_thread, _sp, _main) \  
592 - ST_BEGIN_MACRO \  
593 - if (MD_SETJMP((_thread)->context)) \  
594 - _main(); \  
595 - (_thread)->context[6] = (long) (_sp); \  
596 - ST_END_MACRO  
597 -#else  
598 -#error Unknown CPU architecture  
599 -#endif  
600 -  
601 -#define MD_GET_UTIME() \  
602 - return (gethrtime() / 1000) 538 + #include <sys/filio.h>
  539 + extern int getpagesize(void);
  540 +
  541 + #define MD_STACK_GROWS_DOWN
  542 + #define MD_USE_SYSV_ANON_MMAP
  543 + #define MD_ACCEPT_NB_NOT_INHERITED
  544 +
  545 + #define MD_SETJMP(env) setjmp(env)
  546 + #define MD_LONGJMP(env, val) longjmp(env, val)
  547 +
  548 + #if defined(sparc) || defined(__sparc)
  549 + #ifdef _LP64
  550 + #define MD_STACK_PAD_SIZE 4095
  551 + #endif
  552 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  553 + ST_BEGIN_MACRO \
  554 + (void) MD_SETJMP((_thread)->context); \
  555 + (_thread)->context[1] = (long) (_sp); \
  556 + (_thread)->context[2] = (long) _main; \
  557 + ST_END_MACRO
  558 + #elif defined(i386) || defined(__i386)
  559 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  560 + ST_BEGIN_MACRO \
  561 + (void) MD_SETJMP((_thread)->context); \
  562 + (_thread)->context[4] = (long) (_sp); \
  563 + (_thread)->context[5] = (long) _main; \
  564 + ST_END_MACRO
  565 + #elif defined(__amd64__)
  566 + #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  567 + ST_BEGIN_MACRO \
  568 + if (MD_SETJMP((_thread)->context)) \
  569 + _main(); \
  570 + (_thread)->context[6] = (long) (_sp); \
  571 + ST_END_MACRO
  572 + #else
  573 + #error Unknown CPU architecture
  574 + #endif
  575 +
  576 + #define MD_GET_UTIME() \
  577 + return (gethrtime() / 1000)
603 578
604 #else 579 #else
605 -#error Unknown OS 580 + #error Unknown OS
606 #endif /* OS */ 581 #endif /* OS */
607 582
  583 +/*****************************************
  584 + * Other defines
  585 + */
608 #if !defined(MD_HAVE_POLL) && !defined(MD_DONT_HAVE_POLL) 586 #if !defined(MD_HAVE_POLL) && !defined(MD_DONT_HAVE_POLL)
609 -#define MD_HAVE_POLL 587 + #define MD_HAVE_POLL
610 #endif 588 #endif
611 589
612 #ifndef MD_STACK_PAD_SIZE 590 #ifndef MD_STACK_PAD_SIZE
613 -#define MD_STACK_PAD_SIZE 128 591 + #define MD_STACK_PAD_SIZE 128
614 #endif 592 #endif
615 593
616 #if !defined(MD_HAVE_SOCKLEN_T) && !defined(socklen_t) 594 #if !defined(MD_HAVE_SOCKLEN_T) && !defined(socklen_t)
617 -#define socklen_t int 595 + #define socklen_t int
618 #endif 596 #endif
619 597
620 #ifndef MD_CAP_STACK 598 #ifndef MD_CAP_STACK
621 -#define MD_CAP_STACK(var_addr) 599 + #define MD_CAP_STACK(var_addr)
622 #endif 600 #endif
623 601
624 #endif /* !__ST_MD_H__ */ 602 #endif /* !__ST_MD_H__ */