Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r92:b30306fc8a86
Date: 2013-06-11 16:28 +0200
http://bitbucket.org/pypy/stmgc/changeset/b30306fc8a86/

Log:    in-progress

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -35,6 +35,10 @@
   return (P->h_revision == stm_private_rev_num) ||
     (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
 }
+int _stm_is_private(gcptr P)
+{
+  return is_private(P);
+}
 
 /************************************************************/
 
@@ -208,82 +212,89 @@
     }
 }
 
-#if 0
-static gcptr _latest_gcptr(gcptr R)
+gcptr _stm_nonrecord_barrier(gcptr G)
 {
-  /* don't use, for tests only */
+  /* follows the logic in stm_DirectReadBarrier() */
+  struct tx_descriptor *d = thread_descriptor;
+  gcptr P = G;
   revision_t v;
- retry:
-  v = R->h_revision;
-  if (!(v & 1))  // "is a pointer", i.e.
-    {            //      "has a more recent revision"
-      if (v & 2)
+
+  if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
+    {
+    private_from_protected:
+      if (!(((gcptr)P->h_revision)->h_revision & 1))
         {
-          v &= ~2;
-          if (!stmgc_is_young_in(thread_descriptor, (gcptr)v))
-            return NULL;   /* can't access */
+          fprintf(stderr, "_stm_nonrecord_barrier: %p -> NULL "
+                  "private_from_protected but protected changed\n", G);
+          return NULL;
         }
-      R = (gcptr)v;
-      goto retry;
-    }
-  return R;
-}
-
-gcptr _stm_nonrecord_barrier(gcptr obj, int *result)
-{
-  /* warning, this is for tests only, and it is not thread-safe! */
-  struct tx_descriptor *d = thread_descriptor;
-  if (gcptrlist_size(&d->stolen_objects) > 0)
-    stmgc_normalize_stolen_objects();
-
-  enum protection_class_t e = stmgc_classify(obj);
-  if (e == K_PRIVATE)
-    {
-      *result = 2;   /* 'obj' a private object to start with */
-      return obj;
-    }
-  obj = _latest_gcptr(obj);
-  if (obj == NULL)
-    {
-      assert(e == K_PUBLIC);
-      *result = 3;   /* can't check anything: we'd need foreign access */
-      return NULL;
-    }
-  if (stmgc_classify(obj) == K_PRIVATE)
-    {
-      *result = 1;
-      return obj;
+      goto add_in_recent_reads_cache;
     }
 
-  wlog_t *item;
-  G2L_LOOP_FORWARD(d->public_to_private, item)
+  if (P->h_tid & GCFLAG_PUBLIC)
     {
-      gcptr R = item->addr;
-      gcptr L = item->val;
-      if (_latest_gcptr(R) == obj)
+      while (v = ACCESS_ONCE(P->h_revision), !(v & 1))
         {
-          /* 'obj' has a private version.  The way we detect this lets us
-             find it even if we already have a committed version that
-             will cause conflict. */
-          *result = 1;
-          return L;
+          if (v & 2)
+            goto follow_stub;
+
+          P = (gcptr)v;
+          assert(P->h_tid & GCFLAG_PUBLIC);
         }
-    } G2L_LOOP_END;
 
-  if (obj->h_revision > d->start_time)
-    {
-      /* 'obj' has no private version, and the public version was modified */
-      *result = -1;
-      return NULL;
+      if (P->h_tid & GCFLAG_PUBLIC_TO_PRIVATE)
+        {
+          wlog_t *item;
+          G2L_FIND(d->public_to_private, P, item, goto no_private_obj);
+
+          P = item->val;
+        found_in_stolen_objects:
+          assert(!(P->h_tid & GCFLAG_PUBLIC));
+          assert(is_private(P));
+          fprintf(stderr, "_stm_nonrecord_barrier: %p -> %p "
+                  "public_to_private\n", G, P);
+          return P;
+
+        no_private_obj:;
+          gcptr L = _stm_find_stolen_objects(d, P);
+          if (L != NULL)
+            {
+              P = L;
+              goto found_in_stolen_objects;
+            }
+        }
+
+      if (UNLIKELY(v > d->start_time))
+        {
+          fprintf(stderr, "_stm_nonrecord_barrier: %p -> NULL changed\n", G);
+          return NULL;   // object too recent
+        }
+      fprintf(stderr, "_stm_nonrecord_barrier: %p -> %p public\n", G, P);
     }
   else
     {
-      /* 'obj' has only an up-to-date public version */
-      *result = 0;
-      return obj;
+      fprintf(stderr, "_stm_nonrecord_barrier: %p -> %p protected\n", G, P);
+    }
+
+ register_in_list_of_read_objects:
+ add_in_recent_reads_cache:
+  return P;
+
+ follow_stub:;
+  P = (gcptr)(v - 2);
+  assert(!(P->h_tid & GCFLAG_PUBLIC));
+  if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
+    {
+      fprintf(stderr, "_stm_nonrecord_barrier: %p -> %p handle "
+              "private_from_protected\n", G, P);
+      goto private_from_protected;
+    }
+  else
+    {
+      fprintf(stderr, "read_barrier: %p -> %p handle\n", G, P);
+      goto register_in_list_of_read_objects;
     }
 }
-#endif
 
 #if 0
 void *stm_DirectReadBarrierFromR(void *G1, void *R_Container1, size_t offset)
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -164,7 +164,9 @@
 gcptr stm_DirectReadBarrier(gcptr);
 gcptr stm_RepeatReadBarrier(gcptr);
 gcptr stm_WriteBarrier(gcptr);
-gcptr _stm_nonrecord_barrier(gcptr, int *);
+gcptr _stm_nonrecord_barrier(gcptr);  /* debugging: read barrier, but
+                                         not recording anything */
+int _stm_is_private(gcptr);  /* debugging */
 gcptr stm_get_private_from_protected(long);  /* debugging */
 gcptr stm_get_read_obj(long);  /* debugging */
 gcptr stmgc_duplicate(gcptr);
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -96,3 +96,20 @@
     }
     gcptrlist_clear(&d->public_descriptor->stolen_objects);
 }
+
+gcptr _stm_find_stolen_objects(struct tx_descriptor *d, gcptr obj)
+{
+    /* read-only, for debugging */
+    long i, size = d->public_descriptor->stolen_objects.size;
+    gcptr *items = d->public_descriptor->stolen_objects.items;
+
+    for (i = 0; i < size; i += 2) {
+        gcptr B = items[i];
+        gcptr L = items[i + 1];
+
+        assert(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
+        if (B == obj)
+            return L;
+    }
+    return NULL;
+}
diff --git a/c4/steal.h b/c4/steal.h
--- a/c4/steal.h
+++ b/c4/steal.h
@@ -11,6 +11,7 @@
 void stm_steal_stub(gcptr);
 gcptr stm_get_stolen_obj(long index);   /* debugging */
 void stm_normalize_stolen_objects(struct tx_descriptor *);
+gcptr _stm_find_stolen_objects(struct tx_descriptor *, gcptr);
 
 
 #endif
diff --git a/c3/test/model.py b/c4/test/model.py
copy from c3/test/model.py
copy to c4/test/model.py
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -63,7 +63,8 @@
     //void stmgcpage_add_prebuilt_root(gcptr);
     void stm_clear_between_tests(void);
     //void stmgc_minor_collect(void);
-    //gcptr _stm_nonrecord_barrier(gcptr, int *);
+    gcptr _stm_nonrecord_barrier(gcptr);
+    int _stm_is_private(gcptr);
     int stm_dbgmem_is_active(void *p, int allow_outside);
     void stm_start_sharedlock(void);
     void stm_stop_sharedlock(void);
@@ -436,7 +437,7 @@
 def nalloc_refs(nrefs):
     "Allocate a fresh object from the nursery, with nrefs pointers"
     p = lib.stm_allocate(HDR + WORD * nrefs, 421 + nrefs)
-    assert p.h_revision == lib.get_local_revision()
+    assert p.h_revision == lib.get_private_rev_num()
     for i in range(nrefs):
         assert rawgetptr(p, i) == ffi.NULL   # must already be zero-filled
     return p
diff --git a/c3/test/test_random.py b/c4/test/test_random.py
copy from c3/test/test_random.py
copy to c4/test/test_random.py
--- a/c3/test/test_random.py
+++ b/c4/test/test_random.py
@@ -191,12 +191,10 @@
         return newextra
 
     def nonrecord_barrier(self, ptr):
-        result = ffi.new("int *")
-        ptr = lib._stm_nonrecord_barrier(ptr, result)
-        return ptr, result[0]
+        return lib._stm_nonrecord_barrier(ptr)
 
     def is_private(self, ptr):
-        return ptr.h_revision == lib.get_local_revision()
+        return lib._stm_is_private(ptr)
 
     def check_valid(self, lst):
         lst = list(lst)
@@ -207,23 +205,18 @@
                 continue
             self.check(p)
 
-            ptr, result = self.nonrecord_barrier(p.ptr)
-            if ptr == ffi.NULL and result == 3:
-                continue    # can't check anything: we'd need foreign access
+            ptr = self.nonrecord_barrier(p.ptr)
             has_private_copy = p.obj in self.current_rev.content
-            assert has_private_copy == (result >= 1)
             if has_private_copy:
+                assert ptr != ffi.NULL and self.is_private(ptr)
                 content = self.current_rev.content[p.obj]
             else:
                 try:
                     content = self.current_rev._try_read(p.obj)
-                    is_too_recent = False
                 except model.Deleted:
-                    is_too_recent = True
-                if result < 0:
-                    assert is_too_recent
-                if is_too_recent:
-                    continue     # can't really check more in this case
+                    assert ptr == ffi.NULL
+                    continue
+                assert ptr != ffi.NULL and not self.is_private(ptr)
 
             self.check_not_free(ptr)
             assert lib.rawgetptr(ptr, 2) == p.obj.identity
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to