48
49
# ifdef DEBUG_THREADS
49
/* GC_printf1("FindTopOfStack start at sp = %p\n", frame); */
50
/* GC_printf("FindTopOfStack start at sp = %p\n", frame); */
52
if (frame->savedSP == 0) break;
53
/* if there are no more stack frames, stop */
53
if (frame->savedSP == 0)
55
/* if there are no more stack frames, stop */
55
57
frame = (StackFrame*)frame->savedSP;
57
59
/* we do these next two checks after going to the next frame
58
60
because the LR for the first stack frame in the loop
59
61
is not set up on purpose, so we shouldn't check it. */
60
if ((frame->savedLR & ~3) == 0) break; /* if the next LR is bogus, stop */
61
if ((~(frame->savedLR) & ~3) == 0) break; /* ditto */
62
if ((frame->savedLR & ~3) == 0)
63
break; /* if the next LR is bogus, stop */
64
if ((~(frame->savedLR) & ~3) == 0)
64
68
# ifdef DEBUG_THREADS
65
/* GC_printf1("FindTopOfStack finish at sp = %p\n", frame); */
69
/* GC_printf("FindTopOfStack finish at sp = %p\n", frame); */
68
72
return (unsigned long)frame;
71
75
#ifdef DARWIN_DONT_PARSE_STACK
72
void GC_push_all_stacks() {
76
void GC_push_all_stacks()
79
ppc_thread_state_t state;
81
i386_thread_state_t state;
83
# error FIXME for non-x86 || ppc architectures
85
mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
83
GC_THREAD_STATE_T state;
84
/* MACHINE_THREAD_STATE_COUNT doesn't seem to be defined everywhere. */
85
/* Hence we use our own version. */
86
mach_msg_type_number_t thread_state_count = GC_MACH_THREAD_STATE_COUNT;
87
88
me = pthread_self();
88
if (!GC_thr_initialized) GC_thr_init();
90
for(i=0;i<THREAD_TABLE_SZ;i++) {
91
for(p=GC_threads[i];p!=0;p=p->next) {
92
if(p -> flags & FINISHED) continue;
93
if(pthread_equal(p->id,me)) {
89
if (!GC_thr_initialized)
92
for(i = 0; i < THREAD_TABLE_SZ; i++) {
93
for(p = GC_threads[i]; p != 0; p = p->next) {
94
if(p->flags & FINISHED) continue;
95
if(pthread_equal(p->id, me)) {
94
96
lo = GC_approx_sp();
96
98
/* Get the thread state (registers, etc) */
98
p->stop_info.mach_thread,
101
&thread_state_count);
102
if(r != KERN_SUCCESS) ABORT("thread_get_state failed");
107
GC_push_one(state.eax);
108
GC_push_one(state.ebx);
109
GC_push_one(state.ecx);
110
GC_push_one(state.edx);
111
GC_push_one(state.edi);
112
GC_push_one(state.esi);
113
GC_push_one(state.ebp);
114
#elif defined(POWERPC)
115
lo = (void*)(state.r1 - PPC_RED_ZONE_SIZE);
117
GC_push_one(state.r0);
118
GC_push_one(state.r2);
119
GC_push_one(state.r3);
120
GC_push_one(state.r4);
121
GC_push_one(state.r5);
122
GC_push_one(state.r6);
123
GC_push_one(state.r7);
124
GC_push_one(state.r8);
125
GC_push_one(state.r9);
126
GC_push_one(state.r10);
127
GC_push_one(state.r11);
128
GC_push_one(state.r12);
129
GC_push_one(state.r13);
130
GC_push_one(state.r14);
131
GC_push_one(state.r15);
132
GC_push_one(state.r16);
133
GC_push_one(state.r17);
134
GC_push_one(state.r18);
135
GC_push_one(state.r19);
136
GC_push_one(state.r20);
137
GC_push_one(state.r21);
138
GC_push_one(state.r22);
139
GC_push_one(state.r23);
140
GC_push_one(state.r24);
141
GC_push_one(state.r25);
142
GC_push_one(state.r26);
143
GC_push_one(state.r27);
144
GC_push_one(state.r28);
145
GC_push_one(state.r29);
146
GC_push_one(state.r30);
147
GC_push_one(state.r31);
149
# error FIXME for non-x86 || ppc architectures
99
r = thread_get_state(p->stop_info.mach_thread, GC_MACH_THREAD_STATE,
100
(natural_t*)&state, &thread_state_count);
102
# ifdef DEBUG_THREADS
103
GC_printf("thread_get_state return value = %d\n", r);
106
if(r != KERN_SUCCESS)
107
ABORT("thread_get_state failed");
110
lo = (void*)state . THREAD_FLD (esp);
111
GC_push_one(state . THREAD_FLD (eax));
112
GC_push_one(state . THREAD_FLD (ebx));
113
GC_push_one(state . THREAD_FLD (ecx));
114
GC_push_one(state . THREAD_FLD (edx));
115
GC_push_one(state . THREAD_FLD (edi));
116
GC_push_one(state . THREAD_FLD (esi));
117
GC_push_one(state . THREAD_FLD (ebp));
119
# elif defined(X86_64)
120
lo = (void*)state . THREAD_FLD (rsp);
121
GC_push_one(state . THREAD_FLD (rax));
122
GC_push_one(state . THREAD_FLD (rbx));
123
GC_push_one(state . THREAD_FLD (rcx));
124
GC_push_one(state . THREAD_FLD (rdx));
125
GC_push_one(state . THREAD_FLD (rdi));
126
GC_push_one(state . THREAD_FLD (rsi));
127
GC_push_one(state . THREAD_FLD (rbp));
128
GC_push_one(state . THREAD_FLD (rsp));
129
GC_push_one(state . THREAD_FLD (r8));
130
GC_push_one(state . THREAD_FLD (r9));
131
GC_push_one(state . THREAD_FLD (r10));
132
GC_push_one(state . THREAD_FLD (r11));
133
GC_push_one(state . THREAD_FLD (r12));
134
GC_push_one(state . THREAD_FLD (r13));
135
GC_push_one(state . THREAD_FLD (r14));
136
GC_push_one(state . THREAD_FLD (r15));
137
GC_push_one(state . THREAD_FLD (rip));
138
GC_push_one(state . THREAD_FLD (rflags));
139
GC_push_one(state . THREAD_FLD (cs));
140
GC_push_one(state . THREAD_FLD (fs));
141
GC_push_one(state . THREAD_FLD (gs));
143
# elif defined(POWERPC)
144
lo = (void*)(state . THREAD_FLD (r1) - PPC_RED_ZONE_SIZE);
146
GC_push_one(state . THREAD_FLD (r0));
147
GC_push_one(state . THREAD_FLD (r2));
148
GC_push_one(state . THREAD_FLD (r3));
149
GC_push_one(state . THREAD_FLD (r4));
150
GC_push_one(state . THREAD_FLD (r5));
151
GC_push_one(state . THREAD_FLD (r6));
152
GC_push_one(state . THREAD_FLD (r7));
153
GC_push_one(state . THREAD_FLD (r8));
154
GC_push_one(state . THREAD_FLD (r9));
155
GC_push_one(state . THREAD_FLD (r10));
156
GC_push_one(state . THREAD_FLD (r11));
157
GC_push_one(state . THREAD_FLD (r12));
158
GC_push_one(state . THREAD_FLD (r13));
159
GC_push_one(state . THREAD_FLD (r14));
160
GC_push_one(state . THREAD_FLD (r15));
161
GC_push_one(state . THREAD_FLD (r16));
162
GC_push_one(state . THREAD_FLD (r17));
163
GC_push_one(state . THREAD_FLD (r18));
164
GC_push_one(state . THREAD_FLD (r19));
165
GC_push_one(state . THREAD_FLD (r20));
166
GC_push_one(state . THREAD_FLD (r21));
167
GC_push_one(state . THREAD_FLD (r22));
168
GC_push_one(state . THREAD_FLD (r23));
169
GC_push_one(state . THREAD_FLD (r24));
170
GC_push_one(state . THREAD_FLD (r25));
171
GC_push_one(state . THREAD_FLD (r26));
172
GC_push_one(state . THREAD_FLD (r27));
173
GC_push_one(state . THREAD_FLD (r28));
174
GC_push_one(state . THREAD_FLD (r29));
175
GC_push_one(state . THREAD_FLD (r30));
176
GC_push_one(state . THREAD_FLD (r31));
178
# error FIXME for non-x86 || ppc architectures
152
181
if(p->flags & MAIN_THREAD)
153
182
hi = GC_stackbottom;
155
184
hi = p->stack_end;
157
GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n",
158
(unsigned long) p -> id,
163
GC_push_all_stack(lo,hi);
186
GC_printf("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n",
187
(unsigned long) p -> id, (unsigned long) lo,
190
GC_push_all_stack(lo, hi);
164
191
} /* for(p=GC_threads[i]...) */
165
192
} /* for(i=0;i<THREAD_TABLE_SZ...) */
168
195
#else /* !DARWIN_DONT_PARSE_STACK; Use FindTopOfStack() */
170
void GC_push_all_stacks() {
176
thread_act_array_t act_list = 0;
177
mach_msg_type_number_t listcount = 0;
179
me = mach_thread_self();
180
if (!GC_thr_initialized) GC_thr_init();
182
my_task = current_task();
183
r = task_threads(my_task, &act_list, &listcount);
184
if(r != KERN_SUCCESS) ABORT("task_threads failed");
185
for(i = 0; i < listcount; i++) {
186
thread_act_t thread = act_list[i];
189
hi = (ptr_t)FindTopOfStack(0);
197
void GC_push_all_stacks()
204
thread_act_array_t act_list = 0;
205
mach_msg_type_number_t listcount = 0;
207
me = mach_thread_self();
208
if (!GC_thr_initialized)
211
my_task = current_task();
212
r = task_threads(my_task, &act_list, &listcount);
213
if(r != KERN_SUCCESS)
214
ABORT("task_threads failed");
215
for(i = 0; i < listcount; i++) {
216
thread_act_t thread = act_list[i];
219
hi = (ptr_t)FindTopOfStack(0);
191
221
# if defined(POWERPC)
192
# if CPP_WORDSZ == 32
193
ppc_thread_state_t info;
195
ppc_thread_state64_t info;
222
GC_THREAD_STATE_T info;
197
223
mach_msg_type_number_t outCount = THREAD_STATE_MAX;
198
r = thread_get_state(thread, MACHINE_THREAD_STATE,
199
(natural_t *)&info, &outCount);
200
if(r != KERN_SUCCESS) ABORT("task_get_state failed");
202
lo = (void*)(info.r1 - PPC_RED_ZONE_SIZE);
203
hi = (ptr_t)FindTopOfStack(info.r1);
205
GC_push_one(info.r0);
206
GC_push_one(info.r2);
207
GC_push_one(info.r3);
208
GC_push_one(info.r4);
209
GC_push_one(info.r5);
210
GC_push_one(info.r6);
211
GC_push_one(info.r7);
212
GC_push_one(info.r8);
213
GC_push_one(info.r9);
214
GC_push_one(info.r10);
215
GC_push_one(info.r11);
216
GC_push_one(info.r12);
217
GC_push_one(info.r13);
218
GC_push_one(info.r14);
219
GC_push_one(info.r15);
220
GC_push_one(info.r16);
221
GC_push_one(info.r17);
222
GC_push_one(info.r18);
223
GC_push_one(info.r19);
224
GC_push_one(info.r20);
225
GC_push_one(info.r21);
226
GC_push_one(info.r22);
227
GC_push_one(info.r23);
228
GC_push_one(info.r24);
229
GC_push_one(info.r25);
230
GC_push_one(info.r26);
231
GC_push_one(info.r27);
232
GC_push_one(info.r28);
233
GC_push_one(info.r29);
234
GC_push_one(info.r30);
235
GC_push_one(info.r31);
224
r = thread_get_state(thread, GC_MACH_THREAD_STATE, (natural_t *)&info,
226
if(r != KERN_SUCCESS)
227
ABORT("task_get_state failed");
229
lo = (void*)(info . THREAD_FLD (r1) - PPC_RED_ZONE_SIZE);
230
hi = (ptr_t)FindTopOfStack(info . THREAD_FLD (r1));
232
GC_push_one(info . THREAD_FLD (r0));
233
GC_push_one(info . THREAD_FLD (r2));
234
GC_push_one(info . THREAD_FLD (r3));
235
GC_push_one(info . THREAD_FLD (r4));
236
GC_push_one(info . THREAD_FLD (r5));
237
GC_push_one(info . THREAD_FLD (r6));
238
GC_push_one(info . THREAD_FLD (r7));
239
GC_push_one(info . THREAD_FLD (r8));
240
GC_push_one(info . THREAD_FLD (r9));
241
GC_push_one(info . THREAD_FLD (r10));
242
GC_push_one(info . THREAD_FLD (r11));
243
GC_push_one(info . THREAD_FLD (r12));
244
GC_push_one(info . THREAD_FLD (r13));
245
GC_push_one(info . THREAD_FLD (r14));
246
GC_push_one(info . THREAD_FLD (r15));
247
GC_push_one(info . THREAD_FLD (r16));
248
GC_push_one(info . THREAD_FLD (r17));
249
GC_push_one(info . THREAD_FLD (r18));
250
GC_push_one(info . THREAD_FLD (r19));
251
GC_push_one(info . THREAD_FLD (r20));
252
GC_push_one(info . THREAD_FLD (r21));
253
GC_push_one(info . THREAD_FLD (r22));
254
GC_push_one(info . THREAD_FLD (r23));
255
GC_push_one(info . THREAD_FLD (r24));
256
GC_push_one(info . THREAD_FLD (r25));
257
GC_push_one(info . THREAD_FLD (r26));
258
GC_push_one(info . THREAD_FLD (r27));
259
GC_push_one(info . THREAD_FLD (r28));
260
GC_push_one(info . THREAD_FLD (r29));
261
GC_push_one(info . THREAD_FLD (r30));
262
GC_push_one(info . THREAD_FLD (r31));
237
265
/* FIXME: Remove after testing: */
238
266
WARN("This is completely untested and likely will not work\n", 0);
239
i386_thread_state_t info;
240
mach_msg_type_number_t outCount = THREAD_STATE_MAX;
241
r = thread_get_state(thread, MACHINE_THREAD_STATE,
242
(natural_t *)&info, &outCount);
243
if(r != KERN_SUCCESS) ABORT("task_get_state failed");
245
lo = (void*)info.esp;
246
hi = (ptr_t)FindTopOfStack(info.esp);
248
GC_push_one(info.eax);
249
GC_push_one(info.ebx);
250
GC_push_one(info.ecx);
251
GC_push_one(info.edx);
252
GC_push_one(info.edi);
253
GC_push_one(info.esi);
254
/* GC_push_one(info.ebp); */
255
/* GC_push_one(info.esp); */
256
GC_push_one(info.ss);
257
GC_push_one(info.eip);
258
GC_push_one(info.cs);
259
GC_push_one(info.ds);
260
GC_push_one(info.es);
261
GC_push_one(info.fs);
262
GC_push_one(info.gs);
263
# endif /* !POWERPC */
267
GC_THREAD_STATE_T info;
268
mach_msg_type_number_t outCount = THREAD_STATE_MAX;
269
r = thread_get_state(thread, GC_MACH_THREAD_STATE, (natural_t *)&info,
271
if(r != KERN_SUCCESS)
272
ABORT("task_get_state failed");
274
lo = (void*)info . THREAD_FLD (esp);
275
hi = (ptr_t)FindTopOfStack(info . THREAD_FLD (esp));
277
GC_push_one(info . THREAD_FLD (eax));
278
GC_push_one(info . THREAD_FLD (ebx));
279
GC_push_one(info . THREAD_FLD (ecx));
280
GC_push_one(info . THREAD_FLD (edx));
281
GC_push_one(info . THREAD_FLD (edi));
282
GC_push_one(info . THREAD_FLD (esi));
283
/* GC_push_one(info . THREAD_FLD (ebp)); */
284
/* GC_push_one(info . THREAD_FLD (esp)); */
285
GC_push_one(info . THREAD_FLD (ss));
286
GC_push_one(info . THREAD_FLD (eip));
287
GC_push_one(info . THREAD_FLD (cs));
288
GC_push_one(info . THREAD_FLD (ds));
289
GC_push_one(info . THREAD_FLD (es));
290
GC_push_one(info . THREAD_FLD (fs));
291
GC_push_one(info . THREAD_FLD (gs));
293
# elif defined(X86_64)
294
GC_THREAD_STATE_T info;
295
mach_msg_type_number_t outCount = THREAD_STATE_MAX;
296
r = thread_get_state(thread, GC_MACH_THREAD_STATE, (natural_t *)&info,
298
if(r != KERN_SUCCESS)
299
ABORT("task_get_state failed");
301
lo = (void*)info . THREAD_FLD (rsp);
302
hi = (ptr_t)FindTopOfStack(info . THREAD_FLD (rsp));
304
GC_push_one(info . THREAD_FLD (rax));
305
GC_push_one(info . THREAD_FLD (rbx));
306
GC_push_one(info . THREAD_FLD (rcx));
307
GC_push_one(info . THREAD_FLD (rdx));
308
GC_push_one(info . THREAD_FLD (rdi));
309
GC_push_one(info . THREAD_FLD (rsi));
310
GC_push_one(info . THREAD_FLD (rbp));
311
GC_push_one(info . THREAD_FLD (rsp));
312
GC_push_one(info . THREAD_FLD (r8));
313
GC_push_one(info . THREAD_FLD (r9));
314
GC_push_one(info . THREAD_FLD (r10));
315
GC_push_one(info . THREAD_FLD (r11));
316
GC_push_one(info . THREAD_FLD (r12));
317
GC_push_one(info . THREAD_FLD (r13));
318
GC_push_one(info . THREAD_FLD (r14));
319
GC_push_one(info . THREAD_FLD (r15));
320
GC_push_one(info . THREAD_FLD (rip));
321
GC_push_one(info . THREAD_FLD (rflags));
322
GC_push_one(info . THREAD_FLD (cs));
323
GC_push_one(info . THREAD_FLD (fs));
324
GC_push_one(info . THREAD_FLD (gs));
327
# error FIXME for non-x86 || ppc architectures
265
330
# if DEBUG_THREADS
266
GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n",
267
(unsigned long) thread,
331
GC_printf("Darwin: Stack for thread 0x%lx = [%p,%p)\n",
332
(unsigned long) thread, lo, hi);
272
GC_push_all_stack(lo, hi);
273
mach_port_deallocate(my_task, thread);
334
GC_push_all_stack(lo, hi);
335
mach_port_deallocate(my_task, thread);
274
336
} /* for(p=GC_threads[i]...) */
275
vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount);
276
mach_port_deallocate(my_task, me);
337
vm_deallocate(my_task, (vm_address_t)act_list,
338
sizeof(thread_t) * listcount);
339
mach_port_deallocate(my_task, me);
278
341
#endif /* !DARWIN_DONT_PARSE_STACK */
400
468
/* We should have previously waited for it to become zero. */
401
469
# endif /* PARALLEL_MARK */
403
/* Loop stopping threads until you have gone over the whole list
404
twice without a new one appearing. thread_create() won't
405
return (and thus the thread stop) until the new thread
406
exists, so there is no window whereby you could stop a
407
thread, recognise it is stopped, but then have a new thread
408
it created before stopping show up later.
416
kern_result = task_threads(my_task, &act_list, &listcount);
417
result = GC_suspend_thread_list(act_list, listcount,
418
prev_list, prevcount);
471
/* Loop stopping threads until you have gone over the whole list
472
twice without a new one appearing. thread_create() won't
473
return (and thus the thread stop) until the new thread
474
exists, so there is no window whereby you could stop a
475
thread, recognise it is stopped, but then have a new thread
476
it created before stopping show up later.
479
/* FIXME: This seems to erroneously stop the parallel marker threads? */
486
kern_result = task_threads(my_task, &act_list, &listcount);
488
if(kern_result == KERN_SUCCESS) {
489
result = GC_suspend_thread_list(act_list, listcount, prev_list,
419
491
changes = result;
493
if(prev_list != NULL) {
494
for(i = 0; i < prevcount; i++)
495
mach_port_deallocate(my_task, prev_list[i]);
497
vm_deallocate(my_task, (vm_address_t)prev_list,
498
sizeof(thread_t) * prevcount);
420
500
prev_list = act_list;
421
501
prevcount = listcount;
423
if(kern_result == KERN_SUCCESS) {
426
for(i = 0; i < listcount; i++)
427
mach_port_deallocate(my_task, act_list[i]);
429
vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount);
504
GC_ASSERT(prev_list != 0);
505
for(i = 0; i < prevcount; i++)
506
mach_port_deallocate(my_task, prev_list[i]);
508
vm_deallocate(my_task, (vm_address_t)act_list,
509
sizeof(thread_t) * listcount);
434
511
# ifdef MPROTECT_VDB
435
512
if(GC_incremental) {
436
extern void GC_mprotect_stop();
513
extern void GC_mprotect_stop();
441
518
# ifdef PARALLEL_MARK
442
519
GC_release_mark_lock();
445
GC_printf1("World stopped from 0x%lx\n", my_thread);
448
mach_port_deallocate(my_task, my_thread);
522
GC_printf("World stopped from 0x%lx\n", (unsigned long)my_thread);
525
mach_port_deallocate(my_task, my_thread);
451
528
/* Caller holds allocation lock, and has held it continuously since */
455
532
task_t my_task = current_task();
456
533
mach_port_t my_thread = mach_thread_self();
459
536
kern_return_t kern_result;
460
537
thread_act_array_t act_list;
461
538
mach_msg_type_number_t listcount;
462
539
struct thread_basic_info info;
463
540
mach_msg_type_number_t outCount = THREAD_INFO_MAX;
465
542
# if DEBUG_THREADS
466
GC_printf0("World starting\n");
543
GC_printf("World starting\n");
469
546
# ifdef MPROTECT_VDB
470
547
if(GC_incremental) {
471
extern void GC_mprotect_resume();
472
GC_mprotect_resume();
548
extern void GC_mprotect_resume();
549
GC_mprotect_resume();
476
553
kern_result = task_threads(my_task, &act_list, &listcount);
477
554
for(i = 0; i < listcount; i++) {
478
555
thread_act_t thread = act_list[i];
479
if (thread != my_thread &&
480
(!GC_use_mach_handler_thread ||
481
(GC_use_mach_handler_thread && GC_mach_handler_thread != thread))) {
556
if (thread != my_thread
557
&& (!GC_use_mach_handler_thread
558
|| (GC_use_mach_handler_thread
559
&& GC_mach_handler_thread != thread))) {
482
560
for(j = 0; j < GC_mach_threads_count; j++) {
483
561
if (thread == GC_mach_threads[j].thread) {
484
562
if (GC_mach_threads[j].already_suspended) {
485
563
# if DEBUG_THREADS
486
GC_printf1("Not resuming already suspended thread %p\n", thread);
564
GC_printf("Not resuming already suspended thread %p\n", thread);
490
568
kern_result = thread_info(thread, THREAD_BASIC_INFO,
491
569
(thread_info_t)&info, &outCount);
492
if(kern_result != KERN_SUCCESS) ABORT("thread_info failed");
570
if(kern_result != KERN_SUCCESS)
571
ABORT("thread_info failed");
493
572
# if DEBUG_THREADS
494
GC_printf2("Thread state for 0x%lx = %d\n", thread,
573
GC_printf("Thread state for 0x%lx = %d\n", (unsigned long)thread,
496
GC_printf1("Resuming 0x%lx\n", thread);
575
GC_printf("Resuming 0x%lx\n", (unsigned long)thread);
498
577
/* Resume the thread */
499
578
kern_result = thread_resume(thread);
500
if(kern_result != KERN_SUCCESS) ABORT("thread_resume failed");
579
if(kern_result != KERN_SUCCESS)
580
ABORT("thread_resume failed");
505
mach_port_deallocate(my_task, thread);
584
mach_port_deallocate(my_task, thread);
507
vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount);
509
mach_port_deallocate(my_task, my_thread);
586
vm_deallocate(my_task, (vm_address_t)act_list,
587
sizeof(thread_t) * listcount);
589
mach_port_deallocate(my_task, my_thread);
510
590
# if DEBUG_THREADS
511
GC_printf0("World started\n");
591
GC_printf("World started\n");
515
void GC_darwin_register_mach_handler_thread(mach_port_t thread) {
595
void GC_darwin_register_mach_handler_thread(mach_port_t thread)
516
597
GC_mach_handler_thread = thread;
517
598
GC_use_mach_handler_thread = 1;