if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
ABORT("pthread_attr_setdetachedstate failed");
+# if defined(HANDLE_FORK) && !defined(THREADS)
+ /* FIXME: See comment in GC_fork_prepare_proc. */
+# endif
+
# undef pthread_create
/* This will call the real pthread function, not our wrapper */
if (pthread_create(&thread, &attr, GC_mprotect_thread, NULL) != 0)
if (THREAD_EQUAL(p -> id, self)) {
me = p;
p -> next = 0;
+# ifdef GC_DARWIN_THREADS
+ /* Update thread Id after fork. */
+ me -> stop_info.mach_thread = mach_thread_self();
+# endif
} else {
# ifdef THREAD_LOCAL_ALLOC
if (!(p -> flags & FINISHED)) {
/* Wait for an ongoing GC to finish, since we can't finish it in */
/* the (one remaining thread in) the child. */
LOCK();
+# if defined(GC_DARWIN_THREADS) && defined(MPROTECT_VDB)
+ if (GC_dirty_maintained) {
+ WARN("GC incremental mode is incompatible with fork() for now\n", 0);
+ /* Currently, it is not allowed to use any GC allocated data */
+ /* or call any GC function in the child (before exec). */
+ /* FIXME: Remove warning when mode implemented in child_proc. */
+ }
+# endif
DISABLE_CANCEL(fork_cancel_state);
/* Following waits may include cancellation points. */
# if defined(PARALLEL_MARK)
# if defined(PARALLEL_MARK)
if (GC_parallel)
GC_release_mark_lock();
+# endif
+# if defined(GC_DARWIN_THREADS) && defined(MPROTECT_VDB)
+ /* FIXME: Since GC_mprotect_thread is not running in the child, */
+ /* GC_dirty_maintained should be switched off gracefully */
+ /* (unprotecting all pages and clearing GC_mach_handler_thread). */
# endif
GC_remove_all_threads_but_me();
# ifdef PARALLEL_MARK
/* GC_allocate_ml and GC_need_to_lock are no longer exported, and */
/* AO_fetch_and_add1() may be unavailable to update a counter. */
(void)GC_call_with_alloc_lock(inc_int_counter, &n_tests);
-# if defined(THREADS) && defined(HANDLE_FORK)
+# if defined(THREADS) && defined(HANDLE_FORK) \
+ && (!defined(DARWIN) || !defined(MPROTECT_VDB) \
+ || defined(NO_INCREMENTAL) || defined(MAKE_BACK_GRAPH))
+ /* FIXME: fork() is not tested on Darwin if incremental mode */
+ /* is on for now (till it would be handled properly). */
if (fork() == 0) {
GC_gcollect();
tiny_reverse_test(0);