summaryrefslogtreecommitdiff
path: root/pthread_support.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2012-02-24 08:29:48 +0100
committerIvan Maidanski <ivmai@mail.ru>2012-02-24 12:08:18 +0100
commitf5af75622d75534e34d2739d3f638c429e993691 (patch)
tree904ba4f2d5b5b16196bfd7cc711d7f3de443dc24 /pthread_support.c
parent8bdc924d4ec8c482c46b720eec011ca062e6fcfd (diff)
Fix fork() handling for Darwin partially
(still not handled well for Darwin if GC incremental mode is on) * os_dep.c (GC_dirty_init): Add FIXME regarding fork (Darwin). * pthread_support.c (GC_remove_all_threads_but_me): Update mach_thread for "me" (Darwin). * pthread_support.c (GC_fork_prepare_proc): Output warning if GC_dirty_maintained (if DARWIN and MPROTECT_VDB). * pthread_support.c (GC_fork_prepare_proc, GC_fork_child_proc): Add FIXME (for Darwin). * tests/test.c (run_one_test): Do not test fork() for Darwin with incremental mode on (if HANDLE_FORK); add FIXME.
Diffstat (limited to 'pthread_support.c')
-rw-r--r--pthread_support.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/pthread_support.c b/pthread_support.c
index c78c0a6..775a2fc 100644
--- a/pthread_support.c
+++ b/pthread_support.c
@@ -631,6 +631,10 @@ STATIC void GC_remove_all_threads_but_me(void)
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)) {
@@ -832,6 +836,14 @@ STATIC void GC_fork_prepare_proc(void)
/* 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)
@@ -864,6 +876,11 @@ STATIC void GC_fork_child_proc(void)
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
/* Turn off parallel marking in the child, since we are probably */