Author: Armin Rigo <ar...@tunes.org>
Branch: c7-fork
Changeset: r1069:a1db46a027b5
Date: 2014-03-18 14:06 +0100
http://bitbucket.org/pypy/stmgc/changeset/a1db46a027b5/

Log:    progress

diff --git a/c7/stm/forksupport.c b/c7/stm/forksupport.c
--- a/c7/stm/forksupport.c
+++ b/c7/stm/forksupport.c
@@ -8,10 +8,12 @@
 
 
 static char *fork_big_copy = NULL;
+static stm_thread_local_t *fork_this_tl;
 
 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 pthread_t *_get_cpth(stm_thread_local_t *);/* forward, in setup.c */
 
 
 static void forksupport_prepare(void)
@@ -19,15 +21,35 @@
     if (stm_object_pages == NULL)
         return;
 
-    /* This silently assumes that fork() is not called from transactions.
-       It's hard to check though...
-     */
+    /* This assumes that fork() is not called from transactions.
+       So far we attempt to check this by walking all stm_thread_local_t,
+       marking the one from the current thread, and verifying that it's not
+       running a transaction.  This assumes that the stm_thread_local_t is just
+       a __thread variable, so never changes threads.
+    */
     s_mutex_lock();
 
     synchronize_all_threads();
 
     mutex_pages_lock();
 
+    fork_this_tl = NULL;
+    stm_thread_local_t *tl = stm_all_thread_locals;
+    do {
+        if (pthread_equal(*_get_cpth(tl), pthread_self())) {
+            if (_stm_in_transaction(tl))
+                stm_fatalerror("fork(): cannot be used inside a transaction");
+            if (fork_this_tl != NULL)
+                stm_fatalerror("fork(): found several stm_thread_local_t"
+                               " from the same thread");
+            fork_this_tl = tl;
+        }
+        tl = tl->next;
+    } while (tl != stm_all_thread_locals);
+
+    if (fork_this_tl == NULL)
+        stm_fatalerror("fork(): found no stm_thread_local_t from this thread");
+
     char *big_copy = setup_mmap("stmgc's fork support");
 
     uintptr_t pagenum, endpagenum;
@@ -80,6 +102,15 @@
     mutex_pages_unlock();
     s_mutex_unlock();
 
+    stm_thread_local_t *tl = stm_all_thread_locals;
+    do {
+        stm_thread_local_t *nexttl = tl->next;
+        if (tl != fork_this_tl) {
+            stm_unregister_thread_local(tl);
+        }
+        tl = nexttl;
+    } while (tl != stm_all_thread_locals);
+
     do_or_redo_teardown_after_fork();
 
     assert(fork_big_copy != NULL);
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -139,7 +139,7 @@
     teardown_pages();
 }
 
-void _init_shadow_stack(stm_thread_local_t *tl)
+static void _init_shadow_stack(stm_thread_local_t *tl)
 {
     struct stm_shadowentry_s *s = (struct stm_shadowentry_s *)
         malloc(SHADOW_STACK_SIZE * sizeof(struct stm_shadowentry_s));
@@ -148,13 +148,18 @@
     tl->shadowstack_base = s;
 }
 
-void _done_shadow_stack(stm_thread_local_t *tl)
+static void _done_shadow_stack(stm_thread_local_t *tl)
 {
     free(tl->shadowstack_base);
     tl->shadowstack = NULL;
     tl->shadowstack_base = NULL;
 }
 
+static pthread_t *_get_cpth(stm_thread_local_t *tl)
+{
+    assert(sizeof(pthread_t) <= sizeof(tl->creating_pthread));
+    return (pthread_t *)(tl->creating_pthread);
+}
 
 void stm_register_thread_local(stm_thread_local_t *tl)
 {
@@ -178,6 +183,7 @@
        numbers automatically. */
     num = (num % NB_SEGMENTS) + 1;
     tl->associated_segment_num = num;
+    *_get_cpth(tl) = pthread_self();
     _init_shadow_stack(tl);
     set_gs_register(get_segment_base(num));
     s_mutex_unlock();
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -69,6 +69,7 @@
     /* the next fields are handled internally by the library */
     int associated_segment_num;
     struct stm_thread_local_s *prev, *next;
+    long creating_pthread[4];
 } stm_thread_local_t;
 
 /* this should use llvm's coldcc calling convention,
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to