md.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */
  2. /*
  3. * The contents of this file are subject to the Mozilla Public
  4. * License Version 1.1 (the "License"); you may not use this file
  5. * except in compliance with the License. You may obtain a copy of
  6. * the License at http://www.mozilla.org/MPL/
  7. *
  8. * Software distributed under the License is distributed on an "AS
  9. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10. * implied. See the License for the specific language governing
  11. * rights and limitations under the License.
  12. *
  13. * The Original Code is the Netscape Portable Runtime library.
  14. *
  15. * The Initial Developer of the Original Code is Netscape
  16. * Communications Corporation. Portions created by Netscape are
  17. * Copyright (C) 1994-2000 Netscape Communications Corporation. All
  18. * Rights Reserved.
  19. *
  20. * Contributor(s): Silicon Graphics, Inc.
  21. *
  22. * Portions created by SGI are Copyright (C) 2000-2001 Silicon
  23. * Graphics, Inc. All Rights Reserved.
  24. *
  25. * Alternatively, the contents of this file may be used under the
  26. * terms of the GNU General Public License Version 2 or later (the
  27. * "GPL"), in which case the provisions of the GPL are applicable
  28. * instead of those above. If you wish to allow use of your
  29. * version of this file only under the terms of the GPL and not to
  30. * allow others to use your version of this file under the MPL,
  31. * indicate your decision by deleting the provisions above and
  32. * replace them with the notice and other provisions required by
  33. * the GPL. If you do not delete the provisions above, a recipient
  34. * may use your version of this file under either the MPL or the
  35. * GPL.
  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. #ifndef __ST_MD_H__
  42. #define __ST_MD_H__
  43. #if defined(ETIMEDOUT) && !defined(ETIME)
  44. #define ETIME ETIMEDOUT
  45. #endif
  46. #if defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
  47. #define MAP_ANON MAP_ANONYMOUS
  48. #endif
  49. #ifndef MAP_FAILED
  50. #define MAP_FAILED -1
  51. #endif
  52. /* We define the jmpbuf, because the system's is different in different OS */
  53. typedef struct _st_jmp_buf {
  54. /*
  55. * OS CPU SIZE
  56. * Darwin __amd64__/__x86_64__ long[8]
  57. * Darwin __aarch64__ long[22]
  58. * Linux __i386__ long[6]
  59. * Linux __amd64__/__x86_64__ long[8]
  60. * Linux __aarch64__ long[22]
  61. * Linux __arm__ long[16]
  62. * Linux __mips__/__mips64 long[13]
  63. * Linux __riscv long[14]
  64. * Linux __loongarch64 long[12]
  65. * Cygwin64 __amd64__/__x86_64__ long[8]
  66. */
  67. long __jmpbuf[22];
  68. } _st_jmp_buf_t[1];
  69. extern int _st_md_cxt_save(_st_jmp_buf_t env);
  70. extern void _st_md_cxt_restore(_st_jmp_buf_t env, int val);
  71. /* Always use builtin setjmp/longjmp, use asm code. */
  72. #define MD_USE_BUILTIN_SETJMP
  73. #define MD_SETJMP(env) _st_md_cxt_save(env)
  74. #define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)
  75. #if defined(USE_LIBC_SETJMP)
  76. #error The libc setjmp is not supported now
  77. #endif
  78. /*****************************************
  79. * Platform specifics
  80. */
  81. #if defined (DARWIN)
  82. #define MD_USE_BSD_ANON_MMAP
  83. #define MD_ACCEPT_NB_INHERITED
  84. #define MD_HAVE_SOCKLEN_T
  85. #if defined(__amd64__) || defined(__x86_64__)
  86. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6]))
  87. #elif defined(__aarch64__)
  88. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[13]))
  89. #else
  90. #error Unknown CPU architecture
  91. #endif
  92. #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  93. ST_BEGIN_MACRO \
  94. if (MD_SETJMP((_thread)->context)) \
  95. _main(); \
  96. MD_GET_SP(_thread) = (long) (_sp); \
  97. ST_END_MACRO
  98. #define MD_GET_UTIME() \
  99. struct timeval tv; \
  100. (void) gettimeofday(&tv, NULL); \
  101. return (tv.tv_sec * 1000000LL + tv.tv_usec)
  102. #elif defined (LINUX)
  103. /*
  104. * These are properties of the linux kernel and are the same on every
  105. * flavor and architecture.
  106. */
  107. #define MD_USE_BSD_ANON_MMAP
  108. #define MD_ACCEPT_NB_NOT_INHERITED
  109. /*
  110. * Modern GNU/Linux is Posix.1g compliant.
  111. */
  112. #define MD_HAVE_SOCKLEN_T
  113. /*
  114. * All architectures and flavors of linux have the gettimeofday
  115. * function but if you know of a faster way, use it.
  116. */
  117. #define MD_GET_UTIME() \
  118. struct timeval tv; \
  119. (void) gettimeofday(&tv, NULL); \
  120. return (tv.tv_sec * 1000000LL + tv.tv_usec)
  121. #if defined(__i386__)
  122. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[4]))
  123. #elif defined(__amd64__) || defined(__x86_64__)
  124. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6]))
  125. #elif defined(__aarch64__)
  126. /* https://github.com/ossrs/state-threads/issues/9 */
  127. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[13]))
  128. #elif defined(__arm__)
  129. /* https://github.com/ossrs/state-threads/issues/1#issuecomment-244648573 */
  130. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[8]))
  131. #elif defined(__mips64)
  132. /* https://github.com/ossrs/state-threads/issues/21 */
  133. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
  134. #elif defined(__mips__)
  135. /* https://github.com/ossrs/state-threads/issues/21 */
  136. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
  137. #elif defined(__riscv)
  138. /* https://github.com/ossrs/state-threads/pull/28 */
  139. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
  140. #elif defined(__loongarch64)
  141. /* https://github.com/ossrs/state-threads/issues/24 */
  142. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
  143. #else
  144. #error "Unknown CPU architecture"
  145. #endif /* Cases with common MD_INIT_CONTEXT and different SP locations */
  146. #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  147. ST_BEGIN_MACRO \
  148. if (MD_SETJMP((_thread)->context)) \
  149. _main(); \
  150. MD_GET_SP(_thread) = (long) (_sp); \
  151. ST_END_MACRO
  152. #elif defined (CYGWIN64)
  153. // For CYGWIN64, build SRS on Windows.
  154. #define MD_USE_BSD_ANON_MMAP
  155. #define MD_ACCEPT_NB_INHERITED
  156. #define MD_HAVE_SOCKLEN_T
  157. #define MD_USE_BUILTIN_SETJMP
  158. #if defined(__amd64__) || defined(__x86_64__)
  159. #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6]))
  160. #else
  161. #error Unknown CPU architecture
  162. #endif
  163. #define MD_INIT_CONTEXT(_thread, _sp, _main) \
  164. ST_BEGIN_MACRO \
  165. if (MD_SETJMP((_thread)->context)) \
  166. _main(); \
  167. MD_GET_SP(_thread) = (long) (_sp); \
  168. ST_END_MACRO
  169. #define MD_GET_UTIME() \
  170. struct timeval tv; \
  171. (void) gettimeofday(&tv, NULL); \
  172. return (tv.tv_sec * 1000000LL + tv.tv_usec)
  173. #else
  174. #error Unknown OS
  175. #endif /* OS */
  176. #ifndef MD_STACK_PAD_SIZE
  177. #define MD_STACK_PAD_SIZE 128
  178. #endif
  179. #if !defined(MD_HAVE_SOCKLEN_T) && !defined(socklen_t)
  180. #define socklen_t int
  181. #endif
  182. #ifndef MD_CAP_STACK
  183. #define MD_CAP_STACK(var_addr)
  184. #endif
  185. #endif /* !__ST_MD_H__ */