[pypy-commit] stmgc weakref: try to add weakrefs to demo_random.c

Raemi noreply at buildbot.pypy.org
Thu Jul 18 10:19:01 CEST 2013


Author: Remi Meier <remi.meier at gmail.com>
Branch: weakref
Changeset: r408:e203655b8773
Date: 2013-07-18 10:18 +0200
http://bitbucket.org/pypy/stmgc/changeset/e203655b8773/

Log:	try to add weakrefs to demo_random.c

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -25,27 +25,46 @@
 
 // SUPPORT
 #define GCTID_STRUCT_NODE     123
+#define GCTID_WEAKREF         122
+
+struct node;
+typedef struct node * nodeptr;
+struct weak_node {
+    struct stm_object_s hdr;
+    nodeptr node;
+};
+typedef struct weak_node * weaknodeptr;
+#define WEAKNODE_SIZE  sizeof(struct weak_node)
 
 struct node {
     struct stm_object_s hdr;
     long value;
     revision_t id;
     revision_t hash;
-    struct node *next;
+    nodeptr next;
+    weaknodeptr weakref;
 };
-typedef struct node * nodeptr;
+
+
 
 size_t stmcb_size(gcptr ob)
 {
-    assert(stm_get_tid(ob) == GCTID_STRUCT_NODE);
-    return sizeof(struct node);
+    if (stm_get_tid(ob) == GCTID_STRUCT_NODE)
+        return sizeof(struct node);
+    else if (stm_get_tid(ob) == GCTID_WEAKREF)
+        return WEAKNODE_SIZE;
+    assert(0);
 }
+
 void stmcb_trace(gcptr ob, void visit(gcptr *))
 {
     nodeptr n;
+    if (stm_get_tid(ob) == GCTID_WEAKREF)
+        return;
     assert(stm_get_tid(ob) == GCTID_STRUCT_NODE);
     n = (nodeptr)ob;
     visit((gcptr *)&n->next);
+    visit((gcptr *)&n->weakref);
 }
 
 
@@ -105,6 +124,21 @@
     return (int)(rand_r(&td.thread_seed) % (unsigned int)max);
 }
 
+gcptr get_random_root()
+{
+    int num = get_rand(td.num_roots + 1);
+    if (num == 0)
+        return stm_thread_local_obj;
+    else
+        return td.roots[num - 1];
+}
+
+gcptr get_random_shared_root()
+{
+    int num = get_rand(SHARED_ROOTS);
+    return shared_roots[num];
+}
+
 void copy_roots(gcptr *from, gcptr *to, int num)
 {
     int i;
@@ -192,6 +226,27 @@
     return r;
 }
 
+
+weaknodeptr allocate_weaknodeptr(nodeptr to)
+{
+    weaknodeptr w;
+    push_roots(1);
+    w = (weaknodeptr)stm_weakref_allocate(WEAKNODE_SIZE, GCTID_WEAKREF,
+                                          (gcptr)to);
+    pop_roots(1);
+    return w;
+}
+
+void set_weakref(nodeptr n, nodeptr to)
+{
+    stm_push_root((gcptr)n);
+    weaknodeptr w = allocate_weaknodeptr(to);
+    n = (nodeptr)stm_pop_root();
+    n = (nodeptr)stm_write_barrier((gcptr)n);
+    n->weakref = w;
+    dprintf(("set_weakref %p -> %p -> %p\n", n, w, to));
+}
+
 int is_shared_prebuilt(gcptr p)
 {
     int i;
@@ -448,6 +503,46 @@
     return p;
 }
 
+gcptr weakref_events(gcptr p, gcptr _r, gcptr _sr)
+{
+    nodeptr t;
+    weaknodeptr w;
+    gcptr ptrs[] = {_r, _sr};
+    
+    int i = get_rand(2);
+    int k = get_rand(3);
+    switch (k) {
+    case 0: // check weakref
+        t = (nodeptr)read_barrier(ptrs[i]);
+        w = t->weakref;
+        if(w) {
+            if (w->node) {
+                assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
+                check((gcptr)w->node);
+                return (gcptr)w->node;
+            }
+            else {
+                t->weakref = NULL;
+            }
+        }
+        p = NULL;
+        break;
+    case 1: // set weakref to something
+        if (p)
+            set_weakref((nodeptr)_r, (nodeptr)p);
+        else
+            set_weakref((nodeptr)_r, (nodeptr)get_random_root());
+        p = NULL;
+        break;
+    case 2: // set weakref on shared roots
+        set_weakref((nodeptr)_sr, (nodeptr)get_random_shared_root());
+        p = NULL;
+        break;
+    }
+    return p;
+}
+
+
 gcptr shared_roots_events(gcptr p, gcptr _r, gcptr _sr)
 {
     nodeptr w_sr;
@@ -462,7 +557,7 @@
         break;
     case 2:
         w_sr = (nodeptr)write_barrier(_sr);
-        w_sr->next = (nodeptr)shared_roots[get_rand(SHARED_ROOTS)];
+        w_sr->next = (nodeptr)get_random_shared_root();
         break;
     }
     return p;
@@ -527,18 +622,12 @@
 gcptr do_step(gcptr p)
 {
     gcptr _r, _sr;
-    int num, k;
+    int k;
 
-    num = get_rand(td.num_roots+1);
-    if (num == 0)
-        _r = stm_thread_local_obj;
-    else
-        _r = td.roots[num - 1];
-    
-    num = get_rand(SHARED_ROOTS);
-    _sr = shared_roots[num];
+    _r = get_random_root();
+    _sr = get_random_shared_root();
 
-    k = get_rand(9);
+    k = get_rand(11);
     check(p);
     assert(thread_descriptor->active);
 
@@ -550,6 +639,8 @@
         p = id_hash_events(p, _r, _sr);
     else if (k < 8)
         p = rare_events(p, _r, _sr);
+    else if (k < 10)
+        p = weakref_events(p, _r, _sr);
     else if (get_rand(20) == 1) {
         // transaction break
         fprintf(stdout, "|");
diff --git a/c4/weakref.c b/c4/weakref.c
--- a/c4/weakref.c
+++ b/c4/weakref.c
@@ -5,11 +5,14 @@
 
 gcptr stm_weakref_allocate(size_t size, unsigned long tid, gcptr obj)
 {
+    stm_push_root(obj);
     gcptr weakref = stm_allocate(size, tid);
+    obj = stm_pop_root();
     assert(!(weakref->h_tid & GCFLAG_OLD));   /* 'size' too big? */
     assert(stmgc_size(weakref) == size);
     WEAKREF_PTR(weakref, size) = obj;
     gcptrlist_insert(&thread_descriptor->young_weakrefs, weakref);
+    dprintf(("alloc weakref %p -> %p\n", weakref, obj));
     return weakref;
 }
 


More information about the pypy-commit mailing list