Author: Armin Rigo <ar...@tunes.org>
Branch: c7-fork
Changeset: r1066:c07cd6a30719
Date: 2014-03-18 11:50 +0100
http://bitbucket.org/pypy/stmgc/changeset/c07cd6a30719/

Log:    Hopefully finish fork support

diff --git a/c7/stm/forksupport.c b/c7/stm/forksupport.c
--- a/c7/stm/forksupport.c
+++ b/c7/stm/forksupport.c
@@ -7,7 +7,11 @@
    copy of all shared pages as soon as fork() is called. */
 
 
-static char *fork_big_copy;
+static char *fork_big_copy = NULL;
+
+static char *setup_mmap(char *reason);            /* forward, in setup.c */
+static void do_or_redo_setup_after_fork(void);    /* forward, in setup.c */
+static void do_or_redo_teardown_after_fork(void); /* forward, in setup.c */
 
 
 static void forksupport_prepare(void)
@@ -58,7 +62,7 @@
 
     assert(fork_big_copy != NULL);
     munmap(fork_big_copy, TOTAL_MEMORY);
-    stm_object_pages = NULL;
+    fork_big_copy = NULL;
 
     mutex_pages_unlock();
     s_mutex_unlock();
@@ -69,15 +73,23 @@
     if (stm_object_pages == NULL)
         return;
 
+    /* xxx the stm_thread_local_t belonging to other threads just leak.
+       Note that stm_all_thread_locals is preserved across a
+       stm_teardown/stm_setup sequence. */
+
+    mutex_pages_unlock();
+    s_mutex_unlock();
+
+    do_or_redo_teardown_after_fork();
+
+    assert(fork_big_copy != NULL);
+    assert(stm_object_pages != NULL);
     mremap(fork_big_copy, TOTAL_MEMORY, TOTAL_MEMORY,
            MREMAP_MAYMOVE | MREMAP_FIXED,
            stm_object_pages);
+    fork_big_copy = NULL;
 
-    ...; reset carefully a much bigger part of the state here :-(((
-    memset(pages_privatized, 0, sizeof(pages_privatized));
-
-    mutex_pages_unlock();
-    s_mutex_unlock();
+    do_or_redo_setup_after_fork();
 }
 
 
@@ -88,7 +100,8 @@
     if (!fork_support_ready) {
         int res = pthread_atfork(forksupport_prepare, forksupport_parent,
                                  forksupport_child);
-        assert(res == 0);
+        if (res != 0)
+            stm_fatalerror("pthread_atfork() failed: %m");
         fork_support_ready = true;
     }
 }
diff --git a/c7/stm/forksupport.h b/c7/stm/forksupport.h
deleted file mode 100644
--- a/c7/stm/forksupport.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-static void setup_forksupport(void);
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -32,10 +32,6 @@
     }
 }
 
-static void teardown_nursery(void)
-{
-}
-
 static inline bool _is_in_nursery(object_t *obj)
 {
     assert((uintptr_t)obj >= NURSERY_START);
diff --git a/c7/stm/pages.c b/c7/stm/pages.c
--- a/c7/stm/pages.c
+++ b/c7/stm/pages.c
@@ -25,6 +25,10 @@
 static void teardown_pages(void)
 {
     memset(&pages_ctl, 0, sizeof(pages_ctl));
+}
+
+static void teardown_pages_1(void)
+{
     memset(pages_privatized, 0, sizeof(pages_privatized));
 }
 
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -35,25 +35,8 @@
     return result;
 }
 
-void stm_setup(void)
+static void do_or_redo_setup_after_fork(void)
 {
-    /* Check that some values are acceptable */
-    assert(NB_SEGMENTS <= NB_SEGMENTS_MAX);
-    assert(4096 <= ((uintptr_t)STM_SEGMENT));
-    assert((uintptr_t)STM_SEGMENT == (uintptr_t)STM_PSEGMENT);
-    assert(((uintptr_t)STM_PSEGMENT) + sizeof(*STM_PSEGMENT) <= 8192);
-    assert(2 <= FIRST_READMARKER_PAGE);
-    assert(FIRST_READMARKER_PAGE * 4096UL <= READMARKER_START);
-    assert(READMARKER_START < READMARKER_END);
-    assert(READMARKER_END <= 4096UL * FIRST_OBJECT_PAGE);
-    assert(FIRST_OBJECT_PAGE < NB_PAGES);
-    assert((NB_PAGES * 4096UL) >> 8 <= (FIRST_OBJECT_PAGE * 4096UL) >> 4);
-    assert((END_NURSERY_PAGE * 4096UL) >> 8 <=
-           (FIRST_READMARKER_PAGE * 4096UL));
-    assert(_STM_FAST_ALLOC <= NB_NURSERY_PAGES * 4096);
-
-    stm_object_pages = setup_mmap("initial stm_object_pages mmap()");
-
     long i;
     for (i = 1; i <= NB_SEGMENTS; i++) {
         char *segment_base = get_segment_base(i);
@@ -90,20 +73,38 @@
        so a null read marker means "not read" whatever the
        current transaction_read_version is.
     */
+    setup_nursery();
+}
+
+void stm_setup(void)
+{
+    /* Check that some values are acceptable */
+    assert(NB_SEGMENTS <= NB_SEGMENTS_MAX);
+    assert(4096 <= ((uintptr_t)STM_SEGMENT));
+    assert((uintptr_t)STM_SEGMENT == (uintptr_t)STM_PSEGMENT);
+    assert(((uintptr_t)STM_PSEGMENT) + sizeof(*STM_PSEGMENT) <= 8192);
+    assert(2 <= FIRST_READMARKER_PAGE);
+    assert(FIRST_READMARKER_PAGE * 4096UL <= READMARKER_START);
+    assert(READMARKER_START < READMARKER_END);
+    assert(READMARKER_END <= 4096UL * FIRST_OBJECT_PAGE);
+    assert(FIRST_OBJECT_PAGE < NB_PAGES);
+    assert((NB_PAGES * 4096UL) >> 8 <= (FIRST_OBJECT_PAGE * 4096UL) >> 4);
+    assert((END_NURSERY_PAGE * 4096UL) >> 8 <=
+           (FIRST_READMARKER_PAGE * 4096UL));
+    assert(_STM_FAST_ALLOC <= NB_NURSERY_PAGES * 4096);
+
+    stm_object_pages = setup_mmap("initial stm_object_pages mmap()");
+
+    do_or_redo_setup_after_fork();
 
     setup_sync();
-    setup_nursery();
     setup_gcpage();
     setup_pages();
     setup_forksupport();
 }
 
-void stm_teardown(void)
+static void do_or_redo_teardown_after_fork(void)
 {
-    /* This function is called during testing, but normal programs don't
-       need to call it. */
-    assert(!_has_mutex());
-
     long i;
     for (i = 1; i <= NB_SEGMENTS; i++) {
         struct stm_priv_segment_info_s *pr = get_priv_segment(i);
@@ -117,13 +118,24 @@
         tree_free(pr->callbacks_on_abort);
     }
 
+    teardown_core();
+    teardown_sync_1();
+    teardown_pages_1();
+}
+
+void stm_teardown(void)
+{
+    /* This function is called during testing, but normal programs don't
+       need to call it. */
+    assert(!_has_mutex());
+
+    do_or_redo_teardown_after_fork();
+
     munmap(stm_object_pages, TOTAL_MEMORY);
     stm_object_pages = NULL;
 
-    teardown_core();
     teardown_sync();
     teardown_gcpage();
-    teardown_nursery();
     teardown_pages();
 }
 
@@ -174,6 +186,7 @@
 void stm_unregister_thread_local(stm_thread_local_t *tl)
 {
     s_mutex_lock();
+    assert(tl->prev != NULL);
     assert(tl->next != NULL);
     _done_shadow_stack(tl);
     if (tl == stm_all_thread_locals) {
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -59,7 +59,10 @@
         if (pthread_cond_destroy(&sync_ctl.cond[i]) != 0)
             stm_fatalerror("cond destroy: %m\n");
     }
+}
 
+static void teardown_sync_1(void)
+{
     memset(&sync_ctl, 0, sizeof(sync_ctl));
 }
 
diff --git a/c7/stmgc.c b/c7/stmgc.c
--- a/c7/stmgc.c
+++ b/c7/stmgc.c
@@ -13,7 +13,6 @@
 #include "stm/extra.h"
 #include "stm/fprintcolor.h"
 #include "stm/weakref.h"
-#include "stm/forksupport.h"
 
 #include "stm/misc.c"
 #include "stm/list.c"
@@ -24,6 +23,7 @@
 #include "stm/largemalloc.c"
 #include "stm/nursery.c"
 #include "stm/sync.c"
+#include "stm/forksupport.c"
 #include "stm/setup.c"
 #include "stm/hash_id.c"
 #include "stm/core.c"
@@ -31,4 +31,3 @@
 #include "stm/extra.c"
 #include "stm/fprintcolor.c"
 #include "stm/weakref.c"
-#include "stm/forksupport.c"
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to