Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r336:637f6c9d19f7
Date: 2013-07-01 16:17 +0200
http://bitbucket.org/pypy/stmgc/changeset/637f6c9d19f7/

Log:    stm_enter_callback_call(), for possibly-recursive invocations

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1538,15 +1538,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));
@@ -1594,16 +1593,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/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -193,7 +193,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/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -48,6 +48,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/c4/stmsync.c b/c4/stmsync.c
--- a/c4/stmsync.c
+++ b/c4/stmsync.c
@@ -77,29 +77,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/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -63,6 +63,8 @@
     void stm_set_transaction_length(long length_max);
     _Bool stm_should_break_transaction(void);
     long stm_atomic(long delta);
+    int stm_enter_callback_call(void);
+    void stm_leave_callback_call(int);
 
     /* extra non-public code */
     void printfcolor(char *msg);
diff --git a/c4/test/test_et.py b/c4/test/test_et.py
--- a/c4/test/test_et.py
+++ b/c4/test/test_et.py
@@ -630,7 +630,15 @@
         assert lib.stm_hash(p) != lib.stm_id(p)
     run_parallel(f1, f2)
 
-
-
-    
-    
+def test_enter_callback_call():
+    lib.stm_commit_transaction()
+    x = lib.stm_enter_callback_call()
+    assert x == 0
+    lib.stm_leave_callback_call(x)
+    lib.stm_begin_inevitable_transaction()
+    #
+    lib.stm_finalize()
+    x = lib.stm_enter_callback_call()
+    assert x == 1
+    lib.stm_leave_callback_call(x)
+    lib.stm_initialize_tests(0)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to