patch-boehm-gc_os_dep_c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. $OpenBSD: patch-boehm-gc_os_dep_c,v 1.4 2012/10/17 19:58:21 kurt Exp $
  2. --- boehm-gc/os_dep.c.orig Sun Mar 21 15:34:19 2010
  3. +++ boehm-gc/os_dep.c Tue Oct 9 16:05:42 2012
  4. @@ -380,7 +380,7 @@ static void *tiny_sbrk(ptrdiff_t increment)
  5. #define sbrk tiny_sbrk
  6. # endif /* ECOS */
  7. -#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
  8. +#if defined(NETBSD) && defined(__ELF__)
  9. ptr_t GC_data_start;
  10. void GC_init_netbsd_elf()
  11. @@ -393,6 +393,86 @@ static void *tiny_sbrk(ptrdiff_t increment)
  12. }
  13. #endif
  14. +#if defined(OPENBSD)
  15. + static struct sigaction old_segv_act;
  16. + sigjmp_buf GC_jmp_buf_openbsd;
  17. +
  18. + /*ARGSUSED*/
  19. + void GC_fault_handler_openbsd(int sig)
  20. + {
  21. + siglongjmp(GC_jmp_buf_openbsd, 1);
  22. + }
  23. +
  24. + /* Return the first nonaddressible location > p or bound */
  25. + /* Requires allocation lock. */
  26. + ptr_t GC_find_limit_openbsd(ptr_t p, ptr_t bound)
  27. + {
  28. + static volatile ptr_t result;
  29. + /* Safer if static, since otherwise it may not be */
  30. + /* preserved across the longjmp. Can safely be */
  31. + /* static since it's only called with the */
  32. + /* allocation lock held. */
  33. + struct sigaction act;
  34. + size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
  35. +
  36. + GC_ASSERT(I_HOLD_LOCK());
  37. +
  38. + act.sa_handler = GC_fault_handler_openbsd;
  39. + sigemptyset(&act.sa_mask);
  40. + act.sa_flags = SA_NODEFER | SA_RESTART;
  41. + sigaction(SIGSEGV, &act, &old_segv_act);
  42. +
  43. + if (sigsetjmp(GC_jmp_buf_openbsd, 1) == 0) {
  44. + result = (ptr_t)(((word)(p)) & ~(pgsz-1));
  45. + for (;;) {
  46. + result += pgsz;
  47. + if (result >= bound) {
  48. + result = bound;
  49. + break;
  50. + }
  51. + GC_noop1((word)(*result));
  52. + }
  53. + }
  54. +
  55. + sigaction(SIGSEGV, &old_segv_act, 0);
  56. +
  57. + return(result);
  58. + }
  59. +
  60. + /* Return first addressable location > p or bound */
  61. + /* Requires allocation lock. */
  62. + ptr_t GC_skip_hole_openbsd(ptr_t p, ptr_t bound)
  63. + {
  64. + static volatile ptr_t result;
  65. + struct sigaction act;
  66. + size_t pgsz = (size_t)sysconf(_SC_PAGESIZE);
  67. + static volatile int firstpass;
  68. +
  69. + GC_ASSERT(I_HOLD_LOCK());
  70. +
  71. + act.sa_handler = GC_fault_handler_openbsd;
  72. + sigemptyset(&act.sa_mask);
  73. + act.sa_flags = SA_NODEFER | SA_RESTART;
  74. + sigaction(SIGSEGV, &act, &old_segv_act);
  75. +
  76. + firstpass = 1;
  77. + result = (ptr_t)(((word)(p)) & ~(pgsz-1));
  78. + if (sigsetjmp(GC_jmp_buf_openbsd, 1) != 0 || firstpass) {
  79. + firstpass = 0;
  80. + result += pgsz;
  81. + if (result >= bound) {
  82. + result = bound;
  83. + } else
  84. + GC_noop1((word)(*result));
  85. + }
  86. +
  87. + sigaction(SIGSEGV, &old_segv_act, 0);
  88. +
  89. + return(result);
  90. + }
  91. +#endif
  92. +
  93. +
  94. # ifdef OS2
  95. # include <stddef.h>
  96. @@ -1009,7 +1089,8 @@ ptr_t GC_get_stack_base()
  97. #endif /* FREEBSD_STACKBOTTOM */
  98. #if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \
  99. - && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS)
  100. + && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) \
  101. + && !defined(GC_OPENBSD_THREADS)
  102. ptr_t GC_get_stack_base()
  103. {
  104. @@ -1069,6 +1150,25 @@ ptr_t GC_get_stack_base()
  105. # endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS */
  106. +#if defined(GC_OPENBSD_THREADS)
  107. +
  108. +/* Find the stack using pthread_stackseg_np() */
  109. +
  110. +# include <sys/signal.h>
  111. +# include <pthread.h>
  112. +# include <pthread_np.h>
  113. +
  114. +#define HAVE_GET_STACK_BASE
  115. +
  116. +ptr_t GC_get_stack_base()
  117. +{
  118. + stack_t stack;
  119. + pthread_stackseg_np(pthread_self(), &stack);
  120. + return stack.ss_sp;
  121. +}
  122. +#endif /* GC_OPENBSD_THREADS */
  123. +
  124. +
  125. /*
  126. * Register static data segment(s) as roots.
  127. * If more data segments are added later then they need to be registered
  128. @@ -1440,6 +1540,32 @@ int * etext_addr;
  129. #else /* !OS2 && !Windows && !AMIGA */
  130. +#if defined(OPENBSD)
  131. +
  132. +/*
  133. + * Depending on arch alignment there can be multiple holes
  134. + * between DATASTART & DATAEND. Scan from DATASTART - DATAEND
  135. + * and register each region.
  136. + */
  137. +void GC_register_data_segments(void)
  138. +{
  139. + ptr_t region_start, region_end;
  140. +
  141. + region_start = DATASTART;
  142. +
  143. + for(;;) {
  144. + region_end = GC_find_limit_openbsd(region_start, DATAEND);
  145. + GC_add_roots_inner(region_start, region_end, FALSE);
  146. + if (region_end < DATAEND)
  147. + region_start = GC_skip_hole_openbsd(region_end, DATAEND);
  148. + else
  149. + break;
  150. + }
  151. +}
  152. +
  153. +# else /* !OS2 && !Windows && !AMIGA && !OPENBSD */
  154. +
  155. +
  156. void GC_register_data_segments()
  157. {
  158. # if !defined(PCR) && !defined(SRC_M3) && !defined(MACOS)
  159. @@ -1497,6 +1623,7 @@ void GC_register_data_segments()
  160. /* change. */
  161. }
  162. +# endif /* ! OPENBSD */
  163. # endif /* ! AMIGA */
  164. # endif /* ! MSWIN32 && ! MSWINCE*/
  165. # endif /* ! OS2 */