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