Author: Remi Meier <[email protected]>
Branch: stmgc-c8-gcc
Changeset: r79654:296077e0562c
Date: 2015-09-16 10:55 +0200
http://bitbucket.org/pypy/pypy/changeset/296077e0562c/

Log:    import stmgc with noconflict objects

diff --git a/rpython/translator/stm/src_stm/revision 
b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-7d754bc0f3a7
+6ca47dad66a6
diff --git a/rpython/translator/stm/src_stm/stm/core.c 
b/rpython/translator/stm/src_stm/stm/core.c
--- a/rpython/translator/stm/src_stm/stm/core.c
+++ b/rpython/translator/stm/src_stm/stm/core.c
@@ -12,7 +12,7 @@
 {
     assert(undo->type != TYPE_POSITION_MARKER);
     free(undo->backup);
-    assert(undo->backup = (char*)-88);
+    assert(undo->backup = (char*)0xbb);
     increment_total_allocated(-SLICE_SIZE(undo->slice));
 }
 
@@ -308,7 +308,7 @@
     }
 }
 
-static void reset_modified_from_backup_copies(int segment_num);  /* forward */
+static void reset_modified_from_backup_copies(int segment_num, object_t 
*only_obj);  /* forward */
 
 static bool _stm_validate(void)
 {
@@ -409,6 +409,25 @@
                         if (LIKELY(!_stm_was_read(obj)))
                             continue;
 
+                        /* check for NO_CONFLICT flag in seg0. While its data 
may
+                           not be current there, the flag will be there and is
+                           immutable. (we cannot check in my_segnum bc. we may
+                           only have executed stm_read(o) but not touched its 
pages
+                           yet -> they may be NO_ACCESS */
+                        struct object_s *obj0 = (struct object_s 
*)REAL_ADDRESS(get_segment_base(0), obj);
+                        if (obj0->stm_flags & GCFLAG_NO_CONFLICT) {
+                            /* obj is noconflict and therefore shouldn't cause
+                               an abort. However, from now on, we also assume
+                               that an abort would not roll-back to what is in
+                               the backup copy, as we don't trace the bkcpy
+                               during major GCs.
+                               We choose the approach to reset all our changes
+                               to this obj here, so that we can throw away the
+                               backup copy completely: */
+                            reset_modified_from_backup_copies(my_segnum, obj);
+                            continue;
+                        }
+
                         /* conflict! */
                         dprintf(("_stm_validate() failed for obj %p\n", obj));
 
@@ -418,7 +437,7 @@
                            from the old (but unmodified) version to the newer
                            version.
                         */
-                        reset_modified_from_backup_copies(my_segnum);
+                        reset_modified_from_backup_copies(my_segnum, NULL);
                         timing_write_read_contention(cl->written, undo);
                         needs_abort = true;
                         break;
@@ -1399,7 +1418,7 @@
         invoke_general_finalizers(tl);
 }
 
-static void reset_modified_from_backup_copies(int segment_num)
+static void reset_modified_from_backup_copies(int segment_num, object_t 
*only_obj)
 {
 #pragma push_macro("STM_PSEGMENT")
 #pragma push_macro("STM_SEGMENT")
@@ -1415,7 +1434,11 @@
     for (; undo < end; undo++) {
         if (undo->type == TYPE_POSITION_MARKER)
             continue;
+
         object_t *obj = undo->object;
+        if (only_obj != NULL && obj != only_obj)
+            continue;
+
         char *dst = REAL_ADDRESS(pseg->pub.segment_base, obj);
 
         memcpy(dst + SLICE_OFFSET(undo->slice),
@@ -1427,12 +1450,29 @@
                  SLICE_SIZE(undo->slice), undo->backup));
 
         free_bk(undo);
+
+        if (only_obj != NULL) {
+            assert(IMPLY(only_obj != NULL,
+                         (((struct object_s *)dst)->stm_flags
+                          & (GCFLAG_NO_CONFLICT
+                             | GCFLAG_WRITE_BARRIER
+                             | GCFLAG_WB_EXECUTED))
+                         == (GCFLAG_NO_CONFLICT | GCFLAG_WRITE_BARRIER)));
+            /* copy last element over this one */
+            end--;
+            list->count -= 3;
+            if (undo < end)
+                *undo = *end;
+            undo--;  /* next itr */
+        }
     }
 
-    /* check that all objects have the GCFLAG_WRITE_BARRIER afterwards */
-    check_all_write_barrier_flags(pseg->pub.segment_base, list);
+    if (only_obj == NULL) {
+        /* check that all objects have the GCFLAG_WRITE_BARRIER afterwards */
+        check_all_write_barrier_flags(pseg->pub.segment_base, list);
 
-    list_clear(list);
+        list_clear(list);
+    }
 #pragma pop_macro("STM_SEGMENT")
 #pragma pop_macro("STM_PSEGMENT")
 }
@@ -1468,7 +1508,7 @@
         });
 
     acquire_modification_lock_wr(segment_num);
-    reset_modified_from_backup_copies(segment_num);
+    reset_modified_from_backup_copies(segment_num, NULL);
     release_modification_lock_wr(segment_num);
     _verify_cards_cleared_in_all_lists(pseg);
 
diff --git a/rpython/translator/stm/src_stm/stm/core.h 
b/rpython/translator/stm/src_stm/stm/core.h
--- a/rpython/translator/stm/src_stm/stm/core.h
+++ b/rpython/translator/stm/src_stm/stm/core.h
@@ -43,6 +43,7 @@
     GCFLAG_CARDS_SET = _STM_GCFLAG_CARDS_SET,
     GCFLAG_VISITED = 0x10,
     GCFLAG_FINALIZATION_ORDERING = 0x20,
+    GCFLAG_NO_CONFLICT = _STM_GCFLAG_NO_CONFLICT,
     /* All remaining bits of the 32-bit 'stm_flags' field are taken by
        the "overflow number".  This is a number that identifies the
        "overflow objects" from the current transaction among all old
@@ -50,7 +51,7 @@
        current transaction that have been flushed out of the nursery,
        which occurs if the same transaction allocates too many objects.
     */
-    GCFLAG_OVERFLOW_NUMBER_bit0 = 0x40   /* must be last */
+    GCFLAG_OVERFLOW_NUMBER_bit0 = 0x80   /* must be last */
 };
 
 #define SYNC_QUEUE_SIZE    31
diff --git a/rpython/translator/stm/src_stm/stmgc.h 
b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -162,6 +162,7 @@
 #endif
 
 #define _STM_GCFLAG_WRITE_BARRIER      0x01
+#define _STM_GCFLAG_NO_CONFLICT        0x40
 #define _STM_FAST_ALLOC           (66*1024)
 #define _STM_NSE_SIGNAL_ABORT             1
 #define _STM_NSE_SIGNAL_MAX               2
@@ -780,6 +781,24 @@
 void stm_queue_tracefn(stm_queue_t *queue, void trace(object_t **));
 
 
+
+/* stm_allocate_noconflict() allocates a special kind of object. Validation
+   will never detect conflicts on such an object. However, writes to it can
+   get lost. More precisely: every possible point for validation during a
+   transaction may import a committed version of such objs, thereby resetting
+   it or even contain not-yet-seen values from other (committed) transactions.
+   Hence, changes to such an obj that a transaction commits may or may not
+   propagate to other transactions. */
+__attribute__((always_inline))
+static inline object_t *stm_allocate_noconflict(ssize_t size_rounded_up)
+{
+    object_t *o = stm_allocate(size_rounded_up);
+    o->stm_flags |= _STM_GCFLAG_NO_CONFLICT;
+    return o;
+}
+
+
+
 /* ==================== END ==================== */
 
 extern void (*stmcb_expand_marker)(char *segment_base, uintptr_t odd_number,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to