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