[pypy-commit] stmgc c8-new-page-handling: introduce revision numbers

Raemi noreply at buildbot.pypy.org
Fri Sep 26 10:34:12 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: c8-new-page-handling
Changeset: r1426:fadb937a707d
Date: 2014-09-26 09:57 +0200
http://bitbucket.org/pypy/stmgc/changeset/fadb937a707d/

Log:	introduce revision numbers

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -61,6 +61,7 @@
                            struct stm_commit_log_entry_s *from,
                            struct stm_commit_log_entry_s *to)
 {
+    assert(from->rev_num >= to->rev_num);
     /* walk BACKWARDS the commit log and update the page 'pagenum',
        initially at revision 'from', until we reach the revision 'to'. */
 
@@ -81,6 +82,7 @@
                              struct stm_commit_log_entry_s *from,
                              struct stm_commit_log_entry_s *to)
 {
+    assert(from->rev_num <= to->rev_num);
     if (from == to)
         return;
 
@@ -167,35 +169,18 @@
 
     /* we need to go from 'src_version' to 'target_version'.  This
        might need a walk into the past or the future. */
-    struct stm_commit_log_entry_s *src_version, *target_version, *c1, *c2;
+    struct stm_commit_log_entry_s *src_version, *target_version;
     src_version = get_priv_segment(shared_page_holder)->last_commit_log_entry;
     target_version = STM_PSEGMENT->last_commit_log_entry;
 
     release_modified_objs_lock(shared_page_holder);
     release_all_privatization_locks();
 
-    c1 = src_version;
-    c2 = target_version;
-    while (1) {
-        if (c1 == target_version) {
-            go_to_the_future(pagenum, src_version, target_version);
-            break;
-        }
-        if (c2 == src_version) {
-            go_to_the_past(pagenum, src_version, target_version);
-            break;
-        }
-        c1 = c1->next;
-        if (c1 == (void *)-1 || c1 == NULL) {
-            go_to_the_past(pagenum, src_version, target_version);
-            break;
-        }
-        c2 = c2->next;
-        if (c2 == (void *)-1 || c2 == NULL) {
-            go_to_the_future(pagenum, src_version, target_version);
-            break;
-        }
-    }
+    /* adapt revision of page to our revision: */
+    if (src_version->rev_num < target_version->rev_num)
+        go_to_the_future(pagenum, src_version, target_version);
+    else if (src_version->rev_num > target_version->rev_num)
+        go_to_the_past(pagenum, src_version, target_version);
 }
 
 static void _signal_handler(int sig, siginfo_t *siginfo, void *context)
@@ -245,7 +230,7 @@
             fprintf(stderr, "  INEVITABLE\n");
             return;
         }
-        fprintf(stderr, "  entry at %p: seg %d\n", cl, cl->segment_num);
+        fprintf(stderr, "  entry at %p: seg %d, rev %lu\n", cl, cl->segment_num, cl->rev_num);
         struct stm_undo_s *undo = cl->written;
         struct stm_undo_s *end = undo + cl->written_count;
         for (; undo < end; undo++) {
@@ -276,6 +261,9 @@
        ordering things, but later. */
     acquire_modified_objs_lock(STM_SEGMENT->segment_num);
 
+    /* XXXXXXXXXX: we shouldn't be able to update pages while someone else copies
+       from our pages (signal handler / import objs) */
+
     bool needs_abort = false;
     uint64_t segment_copied_from = 0;
     while ((next_cl = cl->next) != NULL) {
@@ -290,10 +278,11 @@
                          or: XXX do we always need to wait?  we should just
                          break out of this loop and let the caller handle it
                          if it wants to */
+
             _stm_collectable_safe_point();
-            acquire_all_privatization_locks();
             continue;
         }
+        assert(next_cl->rev_num > cl->rev_num);
         cl = next_cl;
 
         /*int srcsegnum = cl->segment_num;
@@ -362,6 +351,7 @@
 
     result->next = NULL;
     result->segment_num = STM_SEGMENT->segment_num;
+    result->rev_num = -1;       /* invalid */
     result->written_count = count;
     memcpy(result->written, list->items, count * sizeof(struct stm_undo_s));
     return result;
@@ -376,9 +366,13 @@
 
         /* try to attach to commit log: */
         old = STM_PSEGMENT->last_commit_log_entry;
-        if (old->next == NULL &&
-                __sync_bool_compare_and_swap(&old->next, NULL, new))
-            break;   /* success! */
+        if (old->next == NULL) {
+            if ((uintptr_t)new != -1) /* INEVITABLE */
+                new->rev_num = old->rev_num + 1;
+
+            if (__sync_bool_compare_and_swap(&old->next, NULL, new))
+                break;   /* success! */
+        }
     }
 }
 
@@ -394,6 +388,7 @@
     new = _create_commit_log_entry();
     if (STM_PSEGMENT->transaction_state == TS_INEVITABLE) {
         old = STM_PSEGMENT->last_commit_log_entry;
+        new->rev_num = old->rev_num + 1;
         OPT_ASSERT(old->next == (void *)-1);
 
         bool yes = __sync_bool_compare_and_swap(&old->next, (void*)-1, new);
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -120,10 +120,11 @@
 struct stm_commit_log_entry_s {
     struct stm_commit_log_entry_s *volatile next;
     int segment_num;
+    uint64_t rev_num;
     size_t written_count;
     struct stm_undo_s written[];
 };
-static struct stm_commit_log_entry_s commit_log_root = {NULL, -1, 0};
+static struct stm_commit_log_entry_s commit_log_root = {NULL, -1, 0, 0};
 
 
 static char *stm_object_pages;


More information about the pypy-commit mailing list