2
0

md.h 23 KB

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