[pypy-commit] pypy stmgc-c4: Fix start_new_thread with stm.

arigo noreply at buildbot.pypy.org
Mon Jul 1 17:21:06 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c4
Changeset: r65142:f0f5f39180fd
Date: 2013-07-01 17:13 +0200
http://bitbucket.org/pypy/pypy/changeset/f0f5f39180fd/

Log:	Fix start_new_thread with stm.

diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py
--- a/rpython/memory/gc/stmgc.py
+++ b/rpython/memory/gc/stmgc.py
@@ -53,9 +53,10 @@
                                needs_finalizer=False,
                                is_finalizer_light=False,
                                contains_weakptr=False):
-        ll_assert(not needs_finalizer, 'XXX')
-        ll_assert(not is_finalizer_light, 'XXX')
-        ll_assert(not contains_weakptr, 'XXX')
+        # XXX finalizers are ignored for now
+        #ll_assert(not needs_finalizer, 'XXX needs_finalizer')
+        #ll_assert(not is_finalizer_light, 'XXX is_finalizer_light')
+        ll_assert(not contains_weakptr, 'XXX contains_weakptr')
         # XXX call optimized versions, e.g. if size < GC_NURSERY_SECTION
         return llop.stm_allocate(llmemory.GCREF, size, typeid16)
 
diff --git a/rpython/memory/gctransform/stmframework.py b/rpython/memory/gctransform/stmframework.py
--- a/rpython/memory/gctransform/stmframework.py
+++ b/rpython/memory/gctransform/stmframework.py
@@ -50,12 +50,7 @@
 class StmRootWalker(BaseRootWalker):
 
     def need_thread_support(self, gctransformer, getfn):
-        def thread_start():
-            llop.stm_initialize(lltype.Void)
-        def thread_die():
-            llop.stm_finalize(lltype.Void)
-        self.thread_start_ptr = getfn(thread_start, [], annmodel.s_None)
-        self.thread_die_ptr = getfn(thread_die, [], annmodel.s_None)
+        pass
 
     def walk_stack_roots(self, collect_stack_root):
         raise NotImplementedError
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -47,17 +47,21 @@
 after_external_call._transaction_break_ = True
 
 def enter_callback_call():
-    # XXX assumes that we're not called in a fresh new thread
-    llop.stm_begin_inevitable_transaction(lltype.Void)
-    return 0
+    return llop.stm_enter_callback_call(lltype.Signed)
 enter_callback_call._dont_reach_me_in_del_ = True
 enter_callback_call._transaction_break_ = True
 
-def leave_callback_call(ignored):
-    llop.stm_commit_transaction(lltype.Void)
+def leave_callback_call(token):
+    llop.stm_leave_callback_call(lltype.Void, token)
 leave_callback_call._dont_reach_me_in_del_ = True
 leave_callback_call._transaction_break_ = True
 
+def invoke_around_extcall():
+    """Initialize the STM system.  Must be called once from the start-up."""
+    from rpython.rlib.objectmodel import invoke_around_extcall
+    invoke_around_extcall(before_external_call, after_external_call,
+                          enter_callback_call, leave_callback_call)
+
 # ____________________________________________________________
 
 def make_perform_transaction(func, CONTAINERP):
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -441,6 +441,8 @@
     'stm_change_atomic':      LLOp(),
     'stm_get_atomic':         LLOp(sideeffects=False),
     'stm_perform_transaction':LLOp(),
+    'stm_enter_callback_call':LLOp(),
+    'stm_leave_callback_call':LLOp(),
 
     'stm_threadlocalref_get': LLOp(sideeffects=False),
     'stm_threadlocalref_set': LLOp(),
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -604,6 +604,8 @@
     OP_STM_THREADLOCAL_GET = _OP_STM
     OP_STM_THREADLOCAL_SET = _OP_STM
     OP_STM_PERFORM_TRANSACTION = _OP_STM
+    OP_STM_ENTER_CALLBACK_CALL = _OP_STM
+    OP_STM_LEAVE_CALLBACK_CALL = _OP_STM
 
 
     def OP_PTR_NONZERO(self, op):
diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -151,6 +151,14 @@
     arg1 = funcgen.expr(op.args[1])
     return 'stm_perform_transaction((gcptr)%s, %s);' % (arg0, arg1)
 
+def stm_enter_callback_call(funcgen, op):
+    result = funcgen.expr(op.result)
+    return '%s = stm_enter_callback_call();' % (result,)
+
+def stm_leave_callback_call(funcgen, op):
+    arg0 = funcgen.expr(op.args[0])
+    return 'stm_leave_callback_call(%s);' % (arg0,)
+
 
 def op_stm(funcgen, op):
     func = globals()[op.opname]
diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -1539,15 +1539,14 @@
 
 __thread gcptr stm_thread_local_obj;
 
-int DescriptorInit(void)
+void DescriptorInit(void)
 {
   if (GCFLAG_PREBUILT != PREBUILT_FLAGS)
     {
       stm_fatalerror("fix PREBUILT_FLAGS in stmgc.h by giving "
                      "it the same value as GCFLAG_PREBUILT!\n");
     }
-
-  if (thread_descriptor == NULL)
+  else
     {
       revision_t i;
       struct tx_descriptor *d = stm_malloc(sizeof(struct tx_descriptor));
@@ -1595,16 +1594,14 @@
       d->tx_next = stm_tx_head;
       if (d->tx_next != NULL) d->tx_next->tx_prev = d;
       stm_tx_head = d;
+      assert(thread_descriptor == NULL);
       thread_descriptor = d;
 
       dprintf(("[%lx] pthread %lx starting\n",
                (long)d->public_descriptor_index, (long)pthread_self()));
 
       stmgcpage_init_tls();
-      return 1;
     }
-  else
-    return 0;
 }
 
 void DescriptorDone(void)
diff --git a/rpython/translator/stm/src_stm/et.h b/rpython/translator/stm/src_stm/et.h
--- a/rpython/translator/stm/src_stm/et.h
+++ b/rpython/translator/stm/src_stm/et.h
@@ -194,7 +194,7 @@
 _Bool stm_has_got_any_lock(struct tx_descriptor *);
 
 struct tx_public_descriptor *stm_get_free_public_descriptor(revision_t *);
-int DescriptorInit(void);
+void DescriptorInit(void);
 void DescriptorDone(void);
 
 #endif  /* _ET_H */
diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-bf56c12295c8
+637f6c9d19f7
diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -49,6 +49,12 @@
 void stm_initialize(void);
 void stm_finalize(void);
 
+/* alternate initializers/deinitializers, to use for places that may or
+   may not be recursive, like callbacks from C code.  The return value
+   of the first one must be passed as argument to the second. */
+int stm_enter_callback_call(void);
+void stm_leave_callback_call(int);
+
 /* read/write barriers (the most general versions only for now) */
 #if 0     // (optimized version below)
 gcptr stm_read_barrier(gcptr);
diff --git a/rpython/translator/stm/src_stm/stmsync.c b/rpython/translator/stm/src_stm/stmsync.c
--- a/rpython/translator/stm/src_stm/stmsync.c
+++ b/rpython/translator/stm/src_stm/stmsync.c
@@ -78,29 +78,46 @@
     d->max_aborts = max_aborts;
 }
 
+int stm_enter_callback_call(void)
+{
+    int token = (thread_descriptor == NULL);
+    if (token == 1) {
+        stmgcpage_acquire_global_lock();
+        DescriptorInit();
+        stmgc_init_nursery();
+        init_shadowstack();
+        stmgcpage_release_global_lock();
+    }
+    BeginInevitableTransaction();
+    return token;
+}
+
+void stm_leave_callback_call(int token)
+{
+    if (token == 1)
+        stmgc_minor_collect();   /* force everything out of the nursery */
+
+    CommitTransaction();
+
+    if (token == 1) {
+        stmgcpage_acquire_global_lock();
+        done_shadowstack();
+        stmgc_done_nursery();
+        DescriptorDone();
+        stmgcpage_release_global_lock();
+    }
+}
+
 void stm_initialize(void)
 {
-    stmgcpage_acquire_global_lock();
-    int r = DescriptorInit();
+    int r = stm_enter_callback_call();
     if (r != 1)
-        stm_fatalerror("stm_initialize: DescriptorInit failure\n");
-    stmgc_init_nursery();
-    init_shadowstack();
-    //stmgcpage_init_tls();
-    stmgcpage_release_global_lock();
-    BeginInevitableTransaction();
+        stm_fatalerror("stm_initialize: already initialized\n");
 }
 
 void stm_finalize(void)
 {
-    stmgc_minor_collect();   /* force everything out of the nursery */
-    CommitTransaction();
-    stmgcpage_acquire_global_lock();
-    //stmgcpage_done_tls();
-    done_shadowstack();
-    stmgc_done_nursery();
-    DescriptorDone();
-    stmgcpage_release_global_lock();
+    stm_leave_callback_call(1);
 }
 
 /************************************************************/
diff --git a/rpython/translator/stm/test/targetdemo2.py b/rpython/translator/stm/test/targetdemo2.py
--- a/rpython/translator/stm/test/targetdemo2.py
+++ b/rpython/translator/stm/test/targetdemo2.py
@@ -1,7 +1,7 @@
 import time
 from rpython.rlib import rthread
 from rpython.rlib import rstm, jit
-from rpython.rlib.objectmodel import invoke_around_extcall, we_are_translated
+from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.objectmodel import compute_identity_hash
 from rpython.rlib.debug import ll_assert
 from rpython.rtyper.lltypesystem import lltype, rffi, rclass
@@ -250,8 +250,7 @@
 def setup_threads():
     #space.threadlocals.setup_threads(space)
     bootstrapper.setup()
-    invoke_around_extcall(rstm.before_external_call, rstm.after_external_call,
-                          rstm.enter_callback_call, rstm.leave_callback_call)
+    rstm.invoke_around_extcall()
 
 def start_thread(args):
     bootstrapper.acquire(args)
diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -62,12 +62,11 @@
         glob = Global()
         #
         def threadfn():
-            rthread.gc_thread_start()
             x = Global()
             x.value = 0
             glob.seen = x
-            rthread.gc_thread_die()
         def entry_point(argv):
+            rstm.invoke_around_extcall()
             glob.seen = None
             rthread.start_new_thread(threadfn, ())
             while glob.seen is None:


More information about the pypy-commit mailing list