Author: Remi Meier <meier...@student.ethz.ch>
Branch: 
Changeset: r273:d01dac528994
Date: 2013-06-25 14:01 +0200
http://bitbucket.org/pypy/stmgc/changeset/d01dac528994/

Log:    do not use backup as shadow-original, always use additional shadow

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -55,7 +55,6 @@
     unsigned int thread_seed;
     gcptr roots[MAXROOTS];
     gcptr roots_outside_perform[MAXROOTS];
-    gcptr current_root;
     int num_roots;
     int num_roots_outside_perform;
     int steps_left;
@@ -68,6 +67,12 @@
 int classify(gcptr p);
 void check(gcptr p);
 
+static int is_private(gcptr P)
+{
+  return (P->h_revision == stm_private_rev_num) ||
+    (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
+}
+
 int get_rand(int max)
 {
     return (int)(rand_r(&td.thread_seed) % (unsigned int)max);
@@ -101,7 +106,8 @@
     int i;
     for (i = 0; i < td.num_roots; i++) {
         check(td.roots[i]);
-        stm_push_root(td.roots[i]);
+        if (td.roots[i])
+            stm_push_root(td.roots[i]);
     }
 }
 
@@ -109,7 +115,8 @@
 {
     int i;
     for (i = td.num_roots - 1; i >= 0; i--) {
-        td.roots[i] = stm_pop_root();
+        if (td.roots[i])
+            td.roots[i] = stm_pop_root();
         check(td.roots[i]);
     }
 }
@@ -173,6 +180,7 @@
         check(p);
         w = stm_write_barrier(p);
         check(w);
+        assert(is_private(w));
     }
     return w;
 }
@@ -351,7 +359,7 @@
         if (w_t->id) {
             assert(w_t->id == stm_id((gcptr)w_t));
             assert(w_t->id == stm_id((gcptr)_t));
-        } 
+        }
         else {
             w_t = (nodeptr)write_barrier(_t);
             w_t->id = stm_id((gcptr)w_t);
@@ -425,9 +433,7 @@
 int run_me()
 {
     gcptr p = NULL;
-    while (td.steps_left) {
-        td.steps_left--;
-
+    while (td.steps_left-->0) {
         if (td.steps_left % 8 == 0)
             fprintf(stdout, "#");
 
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1120,14 +1120,6 @@
                 break;
             }
         }      
-      else if (P->h_original == (revision_t)B) {
-        /* The backup is the "id object" */
-        assert(!(P->h_tid & GCFLAG_HAS_ID));
-
-        B->h_tid &= ~GCFLAG_BACKUP_COPY;
-        B->h_tid |= GCFLAG_PUBLIC;
-        B->h_revision = (revision_t)P;
-      }
       else
         {
           stmgcpage_free(B);
@@ -1159,7 +1151,7 @@
         {
           assert(!(B->h_tid & GCFLAG_BACKUP_COPY));
           P->h_tid |= GCFLAG_PUBLIC;
-          P->h_tid &= ~GCFLAG_HAS_ID; // just in case
+          assert(!(P->h_tid & GCFLAG_HAS_ID));
           if (!(P->h_tid & GCFLAG_OLD)) P->h_tid |= GCFLAG_NURSERY_MOVED;
           /* P becomes a public outdated object.  It may create an
              exception documented in doc-objects.txt: a public but young
@@ -1168,24 +1160,16 @@
              stealing will follow its h_revision (to B).
           */
         }
-      else if (P->h_original == (revision_t)B) {
-        /* The backup is the "id object".  P becomes outdated. */
-        assert(!(P->h_tid & GCFLAG_HAS_ID));
-        P->h_tid |= GCFLAG_PUBLIC;
-        B->h_tid |= GCFLAG_PUBLIC;
-        B->h_tid &= ~GCFLAG_BACKUP_COPY;
-        if (!(P->h_tid & GCFLAG_OLD)) P->h_tid |= GCFLAG_NURSERY_MOVED;
-      }
       else
         {
           /* copy the backup copy B back over the now-protected object P,
              and then free B, which will not be used any more. */
-
+          assert(!(P->h_original) 
+                 || (B->h_original == (revision_t)P->h_original));
+          assert(!(P->h_original && !B->h_original));
           if (P->h_original && !B->h_original) // might occur because of
             B->h_original = P->h_original; //replace_ptr_to_protected_with_stub
 
-          assert(!(P->h_original) 
-                 || (B->h_original == (revision_t)P->h_original));
           size_t size = stmcb_size(B);
           assert(B->h_tid & GCFLAG_BACKUP_COPY);
           memcpy(((char *)P) + offsetof(struct stm_object_s, h_revision),
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -159,18 +159,10 @@
                  p, (gcptr)p->h_original));
         return p->h_original;
     } 
-    else if (!(p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
-               && (p->h_tid & GCFLAG_OLD)) {
-        /* we can be sure that p->h_original doesn't
-           get set during the if and the else-if 
-           
-           XXX: check for priv_from_protected may not be 
-           necessary. only if this func may be called on 
-           another thread's young objects that are made 
-           old at the same time, and we see the OLD flag 
-           before h_original has been set.
-        */
-        dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p));
+    else if (p->h_tid & GCFLAG_OLD) {
+        /* old objects must have an h_original xOR be
+           the original itself. */
+        /* dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p)); */
         return (revision_t)p;
     }
     
@@ -188,35 +180,24 @@
         dprintf(("stm_id(%p) has orig: %p\n", 
                  p, (gcptr)p->h_original));
     }
-    else if (p->h_tid & GCFLAG_OLD) {
-        /* it must be this exact object */
-        result = (revision_t)p;
-        dprintf(("stm_id(%p) is old, orig=0: %p\n", p, p));
-    }
     else {
-        /* must create shadow original object or use
+        /* must create shadow original object XXX: or use
            backup, if exists */
+        
+        /* XXX use stmgcpage_malloc() directly, we don't need to copy
+         * the contents yet */
+        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;
-            /* don't set HAS_ID, otherwise nursery will copy over backup */
-            p->h_original = (revision_t)B;
-            // B->h_tid |= GCFLAG_PUBLIC; done by CommitPrivateFromProtected
-            
-            result = (revision_t)B;
-            dprintf(("stm_id(%p) young, pfp, use backup %p\n", 
-                     p, (gcptr)p->h_original));
+            B->h_original = (revision_t)O;
         }
-        else {
-            /* XXX use stmgcpage_malloc() directly, we don't need to copy
-             * the contents yet */
-            gcptr O = stmgc_duplicate_old(p);
-            p->h_original = (revision_t)O;
-            p->h_tid |= GCFLAG_HAS_ID;
-            O->h_tid |= GCFLAG_PUBLIC;
-            
-            result = (revision_t)O;
-            dprintf(("stm_id(%p) young, make shadow %p\n", p, O));
-        }
+        
+        result = (revision_t)O;
+        dprintf(("stm_id(%p) young, make shadow %p\n", p, O));
     }
     
     spinlock_release(d->public_descriptor->collection_lock);
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -96,6 +96,7 @@
         if (L->h_original) {
             /* L has an original, may be GCFLAG_HAS_ID */
             B->h_original = L->h_original;
+            L->h_tid &= ~GCFLAG_HAS_ID;
         }
         else if (L->h_tid & GCFLAG_OLD) {
             /* If old, it must be the original */
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
@@ -498,10 +498,11 @@
     test_stub_for_refs_from_stolen(old=True)
 
 
-def id_with_stealing(a=0, b=0):
+def id_with_stealing(a, b, c):
     p = palloc_refs(2)
     qlist = []
     rlist = []
+    plist = []
     qid = []
     pid = []
     rid = []
@@ -509,13 +510,14 @@
         r1 = nalloc(HDR)
         q1 = nalloc(HDR)
         p1 = lib.stm_write_barrier(p)   # private copy
+        plist.append(p1)
         qlist.append(q1)
         rlist.append(r1)
-        if a:
+        if c and a:
             # id on young priv
             qid.append(lib.stm_id(q1))
             assert q1.h_tid & GCFLAG_HAS_ID
-        if b:
+        if c and b:
             # id on pub_to_priv
             assert follow_original(p1) == p
             pid.append(lib.stm_id(p1))
@@ -526,21 +528,23 @@
         lib.stm_begin_inevitable_transaction()
         # p old public -> stub -> p1 young prot
         # q1 young prot, r1 young prot
-        if not a:
+        if c and not a:
             # id on young prot
             qid.append(lib.stm_id(q1))
             assert q1.h_tid & GCFLAG_HAS_ID
-        if not b:
+        if c and not b:
             # id on young prot
             assert follow_original(p1) == p
             pid.append(lib.stm_id(p1))
             assert not (p1.h_tid & GCFLAG_HAS_ID)
             
-        r1w = lib.stm_write_barrier(r1) # priv_from_prot
-        assert r1w.h_tid & GCFLAG_PRIVATE_FROM_PROTECTED
-        rid.append(lib.stm_id(r1w))
-        assert not (r1w.h_tid & GCFLAG_HAS_ID) # use backup
-        assert follow_original(r1w) == follow_revision(r1w)
+        r1w = lib.stm_write_barrier(r1)
+        assert classify(r1w) == "private_from_protected"
+        assert not (r1w.h_tid & GCFLAG_OLD)
+        if c:
+                rid.append(lib.stm_id(r1w))
+        # assert not (r1w.h_tid & GCFLAG_HAS_ID) # use backup <- XXX
+        # assert follow_original(r1w) == follow_revision(r1w)
         
         r.set(2)
         r.wait(3)     # wait until the other thread really started
@@ -548,26 +552,45 @@
         r.wait(2)
         r.set(3)
 
-        p2 = lib.stm_read_barrier(p)    # steals
+        assert classify(plist[-1]) == "protected"
+        p2 = lib.stm_read_barrier(plist[-1])    # steals
+        if not c:
+            pid.append(lib.stm_id(p2))
         assert pid[-1] == lib.stm_id(p2)
 
         r2 = lib.getptr(p2, 1)
         r3 = lib.stm_read_barrier(r2)
+        if not c:
+            rid.append(lib.stm_id(r3))
         assert lib.stm_id(r3) == rid[-1]
         
         q2 = lib.getptr(p2, 0)
+        q3 = lib.stm_read_barrier(q2)
+        if not c:
+            qid.append(lib.stm_id(q3))
+
+        assert lib.stm_id(q3) == qid[-1]
         assert lib.stm_id(q2) == qid[-1]
 
-        q3 = lib.stm_read_barrier(q2)
-        assert lib.stm_id(q3) == qid[-1]
-
     run_parallel(f1, f2)
 
 def test_id_with_stealing():
-    id_with_stealing(1, 1)
-    id_with_stealing(1, 0)
-    id_with_stealing(0, 1)
-    id_with_stealing(0, 0)
+    id_with_stealing(1, 1, 0)
+def test_id_with_stealing1():
+    id_with_stealing(1, 0, 0)
+def test_id_with_stealing2():
+    id_with_stealing(0, 1, 0)
+def test_id_with_stealing3():
+    id_with_stealing(0, 0, 0)
+def test_id_with_stealing4():
+    id_with_stealing(1, 1, 1)
+def test_id_with_stealing5():
+    id_with_stealing(1, 0, 1)
+def test_id_with_stealing6():
+    id_with_stealing(0, 1, 1)
+def test_id_with_stealing7():
+    id_with_stealing(0, 0, 1)
+
 
 
 def test_prehash_simple():
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to