[pypy-commit] stmgc default: start using a global commit log

Raemi noreply at buildbot.pypy.org
Wed Sep 3 14:55:41 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: 
Changeset: r1340:03fc557e29dd
Date: 2014-09-03 14:56 +0200
http://bitbucket.org/pypy/stmgc/changeset/03fc557e29dd/

Log:	start using a global commit log

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -3,6 +3,85 @@
 #endif
 
 
+/* ############# commit log ############# */
+
+void _dbg_print_commit_log()
+{
+    struct stm_commit_log_entry_s *cl = &commit_log_root;
+
+    fprintf(stderr, "root (%p, %d)\n", cl->next, cl->segment_num);
+    while ((cl = cl->next)) {
+        size_t i = 0;
+        fprintf(stderr, "elem (%p, %d)\n", cl->next, cl->segment_num);
+        object_t *obj;
+        do {
+            obj = cl->written[i];
+            fprintf(stderr, "-> %p\n", obj);
+            i++;
+        } while ((obj = cl->written[i]));
+    }
+}
+
+void stm_validate(void *free_if_abort)
+{
+    struct stm_commit_log_entry_s *cl = STM_PSEGMENT->last_commit_log_entry;
+
+    /* Don't check 'cl'. This entry is already checked */
+    while ((cl = cl->next)) {
+        size_t i = 0;
+        OPT_ASSERT(cl->segment_num >= 0 && cl->segment_num < NB_SEGMENTS);
+
+        object_t *obj;
+        while ((obj = cl->written[i])) {
+            /* XXX: update our copies */
+
+            if (_stm_was_read(obj)) {
+                free(free_if_abort);
+                stm_abort_transaction();
+            }
+
+            i++;
+        };
+
+        /* last fully validated entry */
+        STM_PSEGMENT->last_commit_log_entry = cl;
+    }
+}
+
+static struct stm_commit_log_entry_s *_create_commit_log_entry()
+{
+    struct list_s *lst = STM_PSEGMENT->modified_old_objects;
+    size_t count = list_count(lst);
+    size_t byte_len = sizeof(struct stm_commit_log_entry_s) + (count + 1) * sizeof(object_t*);
+    struct stm_commit_log_entry_s *result = malloc(byte_len);
+    int i;
+
+    result->next = NULL;
+    result->segment_num = STM_SEGMENT->segment_num;
+    for (i = 0; i < count; i++) {
+        result->written[i] = (object_t*)list_item(lst, i);
+    }
+    result->written[count] = NULL;
+
+    return result;
+}
+
+static void _validate_and_add_to_commit_log()
+{
+    struct stm_commit_log_entry_s *new;
+    void* *to;
+
+    new = _create_commit_log_entry();
+    fprintf(stderr,"%p\n", new);
+    do {
+        stm_validate(new);
+
+        to = (void **)&(STM_PSEGMENT->last_commit_log_entry->next);
+    } while (!__sync_bool_compare_and_swap((void**)to, (void**)NULL, (void**)new));
+}
+
+/* ############# STM ############# */
+
 void _stm_write_slowpath(object_t *obj)
 {
     assert(_seems_to_be_running_transaction());
@@ -159,6 +238,8 @@
 
     minor_collection(1);
 
+    _validate_and_add_to_commit_log();
+
     s_mutex_lock();
 
     assert(STM_SEGMENT->nursery_end == NURSERY_END);
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -52,12 +52,22 @@
     struct list_s *objects_pointing_to_nursery;
     uint8_t privatization_lock;
 
+    struct stm_commit_log_entry_s *last_commit_log_entry;
+
     /* For debugging */
 #ifndef NDEBUG
     pthread_t running_pthread;
 #endif
 };
 
+/* Commit Log things */
+struct stm_commit_log_entry_s {
+    struct stm_commit_log_entry_s *next;
+    int segment_num;
+    object_t *written[];        /* terminated with a NULL ptr */
+};
+static struct stm_commit_log_entry_s commit_log_root = {NULL, -1};
+
 
 static char *stm_object_pages;
 static int stm_object_pages_fd;
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -107,6 +107,7 @@
         pr->pub.segment_base = segment_base;
         pr->modified_old_objects = list_create();
         pr->objects_pointing_to_nursery = list_create();
+        pr->last_commit_log_entry = &commit_log_root;
         pr->pub.transaction_read_version = 0xff;
     }
 
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -67,6 +67,7 @@
 char *_stm_real_address(object_t *o);
 #ifdef STM_TESTS
 #include <stdbool.h>
+void stm_validate(void *free_if_abort);
 bool _stm_was_read(object_t *obj);
 bool _stm_was_written(object_t *obj);
 
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -31,6 +31,8 @@
 void stm_teardown(void);
 void stm_register_thread_local(stm_thread_local_t *tl);
 void stm_unregister_thread_local(stm_thread_local_t *tl);
+void stm_validate(void *free_if_abort);
+bool _check_stm_validate();
 
 bool _checked_stm_write(object_t *obj);
 bool _stm_was_read(object_t *obj);
@@ -124,6 +126,10 @@
     CHECKED(stm_abort_transaction());
 }
 
+bool _check_stm_validate(void) {
+    CHECKED(stm_validate(NULL));
+}
+
 #undef CHECKED
 
 
@@ -314,6 +320,9 @@
 def stm_was_written_card(o):
     return lib._stm_was_written_card(o)
 
+def stm_validate():
+    if lib._check_stm_validate():
+        raise Conflict()
 
 def stm_start_safe_point():
     lib._stm_start_safe_point()
@@ -433,6 +442,7 @@
         #
         if lib._stm_in_transaction(tl2):
             lib._stm_test_switch(tl2)
+            stm_validate() # can raise
 
     def push_root(self, o):
         assert 0


More information about the pypy-commit mailing list