Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r45:bcc91b3b1338
Date: 2013-05-27 18:59 +0200
http://bitbucket.org/pypy/stmgc/changeset/bcc91b3b1338/

Log:    Phew. Found a bug, fixed it by preventing collapse of h_revision
        chains from a GCFLAG_STOLEN object.

diff --git a/c3/Makefile b/c3/Makefile
--- a/c3/Makefile
+++ b/c3/Makefile
@@ -28,7 +28,7 @@
 H_FILES = et.h lists.h nursery.h gcpage.h stmsync.h dbgmem.h fprintcolor.h 
stmgc.h atomic_ops.h stmimpl.h
 C_FILES = et.c lists.c nursery.c gcpage.c stmsync.c dbgmem.c fprintcolor.c
 
-DEBUG = -g -DGC_NURSERY=0x10000 -D_GC_DEBUG=2
+DEBUG = -g -DGC_NURSERY=0x10000 -D_GC_DEBUG=1
 
 
 build-%: %.c ${H_FILES} ${C_FILES}
diff --git a/c3/demo1.c b/c3/demo1.c
--- a/c3/demo1.c
+++ b/c3/demo1.c
@@ -8,9 +8,10 @@
 
 
 #include "stmgc.h"
+#include "fprintcolor.h"
 
 
-#define UPPER_BOUND 10
+#define UPPER_BOUND 100
 #define NUMTHREADS  4
 
 
@@ -45,7 +46,7 @@
 struct node *do_a_check(int seen[], int stress_gc)
 {
   int i;
-  for (i=0; i<UPPER_BOUND; i++)
+  for (i=0; i<NUMTHREADS; i++)
     seen[i] = 0;
 
   struct node *r_n, *prev_n;
@@ -65,19 +66,18 @@
 
       r_n = (struct node *)stm_read_barrier((gcptr)r_n->next);
       long v = r_n->value;
-      assert(0 <= v && v < UPPER_BOUND);
-      if (v == 0)
-        assert(seen[v] < NUMTHREADS);
-      else
-        assert(seen[v] < seen[v-1]);
-      seen[v]++;
+      fprintf(stderr, "\t\t\t\t{ %ld, %p }\n", v, r_n->next);
+      assert(0 <= v && v < UPPER_BOUND * NUMTHREADS);
+      int tn = v / UPPER_BOUND;
+      assert(seen[tn] == v % UPPER_BOUND);
+      seen[tn]++;
     }
   return r_n;
 }
 
 int insert1(gcptr arg1, int retry_counter)
 {
-    int seen[UPPER_BOUND];
+    int seen[NUMTHREADS];
     long nvalue;
     struct node *r_arg;
 
@@ -92,10 +92,13 @@
                                                          GCTID_STRUCT_NODE);
     last = (struct node *)stm_pop_root();
 
+    assert(seen[nvalue / UPPER_BOUND] == nvalue % UPPER_BOUND);
     w_newnode->value = nvalue;
     w_newnode->next = NULL;
+    fprintf(stderr, "DEMO1: %p->value = %ld\n", w_newnode, nvalue);
 
     struct node *w_last = (struct node *)stm_write_barrier((gcptr)last);
+    fprintf(stderr, "DEMO1:   %p->next = %p\n", w_last, w_newnode);
     w_last->next = w_newnode;
 
     return 0;   /* return from stm_perform_transaction() */
@@ -105,18 +108,24 @@
 
 extern void stmgcpage_possibly_major_collect(int force);  /* temp */
 
+static int thr_mynum = 0;
+
 void *demo1(void *arg)
 {
-    int i, status;
+    int i, status, start;
     struct node *w_node;
     stm_initialize();
 
+    start = thr_mynum++;   /* protected by being inevitable here */
+    start *= UPPER_BOUND;
+    fprintf(stderr, "THREAD STARTING: start = %d\n", start);
+
     w_node = (struct node *)stm_allocate(sizeof(struct node),
                                          GCTID_STRUCT_NODE);
 
     for (i=0; i<UPPER_BOUND; i++) {
         w_node = (struct node *)stm_write_barrier((gcptr)w_node);
-        w_node->value = i;
+        w_node->value = start + i;
         stm_push_root((gcptr)w_node);
         stm_perform_transaction((gcptr)w_node, insert1);
         stmgcpage_possibly_major_collect(0); /* temp */
@@ -131,11 +140,15 @@
 
 void final_check(void)
 {
-  int seen[UPPER_BOUND];
+  int i;
+  int seen[NUMTHREADS];
 
   stm_initialize();
   do_a_check(seen, 0);
-  assert(seen[UPPER_BOUND-1] == NUMTHREADS);
+
+  for (i=0; i<NUMTHREADS; i++)
+    assert(seen[i] == UPPER_BOUND);
+
   stm_finalize();
   printf("check ok\n");
 }
diff --git a/c3/et.c b/c3/et.c
--- a/c3/et.c
+++ b/c3/et.c
@@ -93,7 +93,7 @@
       gcptr R_prev = R;
       R = (gcptr)v;
 
-      /* retry */
+    retry_threelevels:
       v = ACCESS_ONCE(R->h_revision);
       if (!(v & 1))  // "is a pointer", i.e.
         {            //      "has a more recent revision"
@@ -103,15 +103,23 @@
           /* we update R_prev->h_revision as a shortcut */
           /* XXX check if this really gives a worse performance than only
              doing this write occasionally based on a counter in d */
-          R = (gcptr)v;
-          if (R->h_revision == stm_local_revision)
+          gcptr R_next = (gcptr)v;
+          if (R_next->h_revision == stm_local_revision)
             {
               /* must not update an older h_revision to go directly to
                  the private copy at the end of a chain of protected
                  objects! */
-              return R;
+              return R_next;
+            }
+          if (R_prev->h_tid & GCFLAG_STOLEN)
+            {
+              /* must not update the h_revision of a stolen object! */
+              R_prev = R;
+              R = R_next;
+              goto retry_threelevels;
             }
           R_prev->h_revision = v;
+          R = R_next;
           goto retry;
         }
     }
@@ -505,7 +513,14 @@
   gcptrlist_clear(&d->list_of_read_objects);
   stmgc_abort_transaction(d);
 
-  fprintf(stderr, "[%lx] abort %d\n", (long)d->my_lock, num);
+  fprintf(stderr,
+          "\n"
+          "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
+          "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
+          "!!!!!!!!!!!!!!!!!!!!!  [%lx] abort %d\n"
+          "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
+          "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
+          "\n", (long)d->my_lock, num);
   if (num != ABRT_MANUAL && d->max_aborts >= 0 && !d->max_aborts--)
     {
       fprintf(stderr, "unexpected abort!\n");
diff --git a/c3/nursery.c b/c3/nursery.c
--- a/c3/nursery.c
+++ b/c3/nursery.c
@@ -1116,7 +1116,7 @@
             g2l_insert(&d->public_to_private, N, L);
             gcptrlist_insert(&d->public_to_young, N);
         }
-        recdump1("STOLEN", R);
+        recdump1("WAS STOLEN", R);
 
         /* then all items from i+2 up to the first NULL are new stubs
            that must be added to d->public_to_young, in the first part
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to