Author: Remi Meier <[email protected]>
Branch: 
Changeset: r1362:248d91849433
Date: 2014-09-05 15:48 +0200
http://bitbucket.org/pypy/stmgc/changeset/248d91849433/

Log:    some cleanup and comments

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -9,23 +9,29 @@
 
 static void bring_page_up_to_date(uintptr_t pagenum)
 {
-    /* pagecopy from somewhere readable, then update
+    /* Assuming pagenum is not yet private in this segment and
+       currently read-protected:
+
+       pagecopy from somewhere readable, then update
        all written objs from that segment */
+
+    assert(!is_shared_log_page(pagenum));
+
+    /* XXX: this may not even be necessary: */
+    assert(STM_PSEGMENT->privatization_lock);
+
     long i;
     int my_segnum = STM_SEGMENT->segment_num;
 
     assert(!is_readable_log_page_in(my_segnum, pagenum));
     assert(!is_private_log_page_in(my_segnum, pagenum));
 
-    /* make readable */
-    assert(STM_PSEGMENT->privatization_lock); /* we hold it, nobody
-                                                 will privatize a page,
-                                                 necessary? */
+    /* privatize and make readable */
     pages_set_protection(my_segnum, pagenum, 1, PROT_READ|PROT_WRITE);
     page_privatize(pagenum);
 
-    assert(!is_shared_log_page(pagenum));
-
+    /* look for a segment where the page is readable (and
+       therefore private): */
     for (i = 0; i < NB_SEGMENTS; i++) {
         if (i == my_segnum)
             continue;
@@ -33,7 +39,9 @@
             continue;
 
         acquire_privatization_lock(i);
-        assert(is_readable_log_page_in(i, pagenum)); /* still... */
+        /* nobody should be able to change this because we have
+           our own privatization lock: */
+        assert(is_readable_log_page_in(i, pagenum));
 
         /* copy the content from there to our segment */
         dprintf(("pagecopy pagenum:%lu, src: %lu, dst:%d\n", pagenum, i, 
my_segnum));
@@ -45,23 +53,25 @@
         acquire_modified_objs_lock(i);
         struct tree_s *tree = get_priv_segment(i)->modified_old_objects;
         wlog_t *item;
-        TREE_LOOP_FORWARD(tree, item);
-        if (item->addr >= pagenum * 4096UL && item->addr < (pagenum + 1) * 
4096UL) {
-            object_t *obj = (object_t*)item->addr;
-            struct object_s* bk_obj = (struct object_s *)item->val;
-            size_t obj_size;
+        TREE_LOOP_FORWARD(tree, item); {
+            if (item->addr >= pagenum * 4096UL && item->addr < (pagenum + 1) * 
4096UL) {
+                /* obj is in range. XXX: no page overlapping objs allowed yet 
*/
 
-            obj_size = stmcb_size_rounded_up(bk_obj);
-            assert(obj_size < 4096); /* XXX */
+                object_t *obj = (object_t*)item->addr;
+                struct object_s* bk_obj = (struct object_s *)item->val;
+                size_t obj_size;
 
-            memcpy(REAL_ADDRESS(STM_SEGMENT->segment_base, obj),
-                   bk_obj, obj_size);
-            assert(obj->stm_flags & GCFLAG_WRITE_BARRIER); /* not written */
-        }
-        TREE_LOOP_END;
+                obj_size = stmcb_size_rounded_up(bk_obj);
+                assert(obj_size < 4096); /* XXX */
+
+                memcpy(REAL_ADDRESS(STM_SEGMENT->segment_base, obj),
+                       bk_obj, obj_size);
+
+                assert(obj->stm_flags & GCFLAG_WRITE_BARRIER); /* bk_obj never 
written */
+            }
+        } TREE_LOOP_END;
 
         release_modified_objs_lock(i);
-
         release_privatization_lock(i);
 
         return;
@@ -76,7 +86,7 @@
     dprintf(("si_addr: %p\n", addr));
     if (addr == NULL || addr < stm_object_pages || addr > 
stm_object_pages+TOTAL_MEMORY) {
         /* actual segfault */
-        /* send to GDB */
+        /* send to GDB (XXX) */
         kill(getpid(), SIGINT);
     }
     /* XXX: should we save 'errno'? */
@@ -117,20 +127,26 @@
 
 static void _update_obj_from(int from_seg, object_t *obj)
 {
+    /* during validation this looks up the obj in the
+       from_seg (backup or normal) and copies the version
+       over the current segment's one */
     char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
     size_t obj_size;
 
     uintptr_t pagenum = (uintptr_t)obj / 4096UL;
     if (!is_private_log_page_in(STM_SEGMENT->segment_num, pagenum)) {
+        /* done in signal handler on first access anyway */
         assert(!is_shared_log_page(pagenum));
         assert(!is_readable_log_page_in(STM_SEGMENT->segment_num, pagenum));
-        return;                 /* only do in sighandler */
+        return;
     }
 
     /* should be readable & private (XXX: maybe not after major GCs) */
     assert(is_readable_log_page_in(from_seg, pagenum));
     assert(is_private_log_page_in(from_seg, pagenum));
 
+    /* look the obj up in the other segment's modified_old_objects to
+       get its backup copy: */
     acquire_modified_objs_lock(from_seg);
 
     struct tree_s *tree = get_priv_segment(from_seg)->modified_old_objects;
@@ -144,7 +160,7 @@
     return;
 
  not_found:
-    /* copy from page */
+    /* copy from page directly (obj is unmodified) */
     obj_size = stmcb_size_rounded_up(
         (struct object_s*)REAL_ADDRESS(get_segment_base(from_seg), obj));
     memcpy(realobj,
@@ -156,6 +172,10 @@
 
 void stm_validate(void *free_if_abort)
 {
+    /* go from last known entry in commit log to the
+       most current one and apply all changes done
+       by other transactions. Abort if we read one of
+       the committed objs. */
     volatile struct stm_commit_log_entry_s *cl = (volatile struct 
stm_commit_log_entry_s *)
         STM_PSEGMENT->last_commit_log_entry;
 
@@ -163,11 +183,10 @@
     bool needs_abort = false;
     /* 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;
-
+        size_t i = 0;
         while ((obj = cl->written[i])) {
             _update_obj_from(cl->segment_num, obj);
 
@@ -181,8 +200,8 @@
         /* last fully validated entry */
         STM_PSEGMENT->last_commit_log_entry = (struct stm_commit_log_entry_s 
*)cl;
     }
+    release_privatization_lock(STM_SEGMENT->segment_num);
 
-    release_privatization_lock(STM_SEGMENT->segment_num);
     if (needs_abort) {
         free(free_if_abort);
         stm_abort_transaction();
@@ -191,6 +210,10 @@
 
 static struct stm_commit_log_entry_s *_create_commit_log_entry()
 {
+    /* puts all modified_old_objects in a new commit log entry */
+
+    // we don't need the privatization lock, as we are only
+    // reading from modified_old_objs and nobody but us can change it
     struct tree_s *tree = STM_PSEGMENT->modified_old_objects;
     size_t count = tree_count(tree);
     size_t byte_len = sizeof(struct stm_commit_log_entry_s) + (count + 1) * 
sizeof(object_t*);
@@ -201,10 +224,10 @@
 
     int i = 0;
     wlog_t *item;
-    TREE_LOOP_FORWARD(tree, item);
-    result->written[i] = (object_t*)item->addr;
-    i++;
-    TREE_LOOP_END;
+    TREE_LOOP_FORWARD(tree, item); {
+        result->written[i] = (object_t*)item->addr;
+        i++;
+    } TREE_LOOP_END;
 
     OPT_ASSERT(count == i);
     result->written[count] = NULL;
@@ -212,26 +235,26 @@
     return result;
 }
 
-static struct stm_commit_log_entry_s *_validate_and_add_to_commit_log()
+static void _validate_and_add_to_commit_log()
 {
     struct stm_commit_log_entry_s *new;
     volatile struct stm_commit_log_entry_s **to;
 
     new = _create_commit_log_entry();
-    fprintf(stderr,"%p\n", new);
     do {
         stm_validate(new);
 
+        /* try attaching to commit log: */
         to = &(STM_PSEGMENT->last_commit_log_entry->next);
     } while (!__sync_bool_compare_and_swap(to, NULL, new));
-
-    return new;
 }
 
 /* ############# STM ############# */
 
 void _privatize_and_protect_other_segments(object_t *obj)
 {
+    /* privatize pages of obj for our segment iff previously
+       the pages were fully shared. */
 #ifndef NDEBUG
     long l;
     for (l = 0; l < NB_SEGMENTS; l++) {
@@ -249,7 +272,8 @@
     obj_size = stmcb_size_rounded_up((struct object_s *)realobj);
     assert(obj_size < 4096); /* XXX */
 
-    /* privatize pages: */
+    /* privatize pages by read-protecting them in other
+       segments and giving us a private copy: */
     assert(is_shared_log_page(first_page));
     /* XXX: change this logic:
        right now, privatization means private in seg0 and private
@@ -423,21 +447,23 @@
 
     _validate_and_add_to_commit_log();
 
+    /* clear WRITE_BARRIER flags, free all backup copies,
+       and clear the tree: */
     acquire_modified_objs_lock(STM_SEGMENT->segment_num);
 
     struct tree_s *tree = STM_PSEGMENT->modified_old_objects;
     wlog_t *item;
-    TREE_LOOP_FORWARD(tree, item);
-    object_t *obj = (object_t*)item->addr;
-    struct object_s* bk_obj = (struct object_s *)item->val;
-    free(bk_obj);
-    obj->stm_flags |= GCFLAG_WRITE_BARRIER;
-    TREE_LOOP_END;
-
+    TREE_LOOP_FORWARD(tree, item); {
+        object_t *obj = (object_t*)item->addr;
+        struct object_s* bk_obj = (struct object_s *)item->val;
+        free(bk_obj);
+        obj->stm_flags |= GCFLAG_WRITE_BARRIER;
+    } TREE_LOOP_END;
     tree_clear(tree);
 
     release_modified_objs_lock(STM_SEGMENT->segment_num);
 
+
     s_mutex_lock();
 
     assert(STM_SEGMENT->nursery_end == NURSERY_END);
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to