[pypy-commit] stmgc default: add atomic transactions in demo_random

Raemi noreply at buildbot.pypy.org
Mon Jul 1 12:33:11 CEST 2013


Author: Remi Meier <meierrem at student.ethz.ch>
Branch: 
Changeset: r328:6eac0903bcb9
Date: 2013-07-01 12:32 +0200
http://bitbucket.org/pypy/stmgc/changeset/6eac0903bcb9/

Log:	add atomic transactions in demo_random

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -60,6 +60,7 @@
     int num_roots_outside_perform;
     int steps_left;
     int interruptible;
+    int atomic;
 };
 __thread struct thread_data td;
 
@@ -74,6 +75,24 @@
     (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
 }
 
+static void inc_atomic()
+{
+    assert(td.interruptible);
+    assert(stm_atomic(0) == td.atomic);
+    td.atomic++;
+    stm_atomic(1);
+    assert(stm_atomic(0) == td.atomic);
+}
+
+static void dec_atomic()
+{
+    assert(td.interruptible);
+    assert(stm_atomic(0) == td.atomic);
+    td.atomic--;
+    stm_atomic(-1);
+    assert(stm_atomic(0) == td.atomic);
+}
+
 int get_rand(int max)
 {
     return (int)(rand_r(&td.thread_seed) % (unsigned int)max);
@@ -254,7 +273,8 @@
     td.thread_seed = default_seed++;
     td.steps_left = STEPS_PER_THREAD;
     td.interruptible = 0;
-    
+    td.atomic = 0;
+
     td.num_roots = PREBUILT + NUMROOTS;
     for (i = 0; i < PREBUILT; i++) {
         if (i % 3 == 0) {
@@ -303,7 +323,7 @@
 gcptr simple_events(gcptr p, gcptr _r, gcptr _sr)
 {
     nodeptr w_r;
-    int k = get_rand(8);
+    int k = get_rand(11);
     int num = get_rand(td.num_roots);
     switch (k) {
     case 0: // remove a root
@@ -338,6 +358,18 @@
         check(p);
         w_r->next = (struct node*)p;
         break;
+    case 8:
+        if (td.interruptible) {
+            inc_atomic();
+        }
+        break;
+    case 9:
+    case 10:
+        /* more likely to be less atomic */
+        if (td.atomic) {
+            dec_atomic();
+        }
+        break;
     }
     return p;
 }
@@ -469,7 +501,7 @@
     td.num_roots = td.num_roots_outside_perform;
     // done & overwritten by the following pop_roots():
     // copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
-
+    td.atomic = 0; // may be set differently on abort
     // refresh td.roots:
     gcptr end_marker = stm_pop_root();
     assert(end_marker == END_MARKER_ON || end_marker == END_MARKER_OFF);
@@ -490,14 +522,26 @@
 int run_me()
 {
     gcptr p = NULL;
-    while (td.steps_left-->0) {
+    while (td.steps_left-->0 || td.atomic) {
         if (td.steps_left % 8 == 0)
             fprintf(stdout, "#");
 
         p = do_step(p);
 
-        if (p == (gcptr)-1)
-            return -1;
+        if (p == (gcptr)-1) {
+            if (td.atomic) {
+                // can't break, well, we could return to perform_transaction
+                // while being atomic. (TODO)
+                // may be true when major gc requested:
+                // assert(stm_should_break_transaction() == 0);
+                assert(stm_atomic(0) == td.atomic);
+                p = NULL;
+            }
+            else {
+                assert(stm_atomic(0) == 0);
+                return -1;
+            }
+        }
     }
     return 0;
 }
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -906,6 +906,8 @@
 long stm_atomic(long delta)
 {
   struct tx_descriptor *d = thread_descriptor;
+  if (delta) // no atomic-checks
+    dprintf(("stm_atomic(%lu)\n", delta));
   d->atomic += delta;
   assert(d->atomic >= 0);
   update_reads_size_limit(d);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -198,9 +198,6 @@
         return (revision_t)p;
     }
     
-    /* XXX: think about if p->h_original needs a volatile read
-       and if we need a memory fence (smp_wmb())... */
-    
     spinlock_acquire(d->public_descriptor->collection_lock, 'I');
     /* old objects must have an h_original xOR be
        the original itself. 
@@ -222,7 +219,6 @@
         gcptr O = stmgc_duplicate_old(p);
         p->h_original = (revision_t)O;
         p->h_tid |= GCFLAG_HAS_ID;
-        O->h_tid |= GCFLAG_PUBLIC;
         
         if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
             gcptr B = (gcptr)p->h_revision;


More information about the pypy-commit mailing list