[pypy-commit] stmgc marker: in-progress

arigo noreply at buildbot.pypy.org
Mon Apr 28 17:16:15 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: marker
Changeset: r1186:a8f77868840a
Date: 2014-04-28 15:40 +0200
http://bitbucket.org/pypy/stmgc/changeset/a8f77868840a/

Log:	in-progress

diff --git a/c7/stm/contention.c b/c7/stm/contention.c
--- a/c7/stm/contention.c
+++ b/c7/stm/contention.c
@@ -196,6 +196,10 @@
         /* We have to signal the other thread to abort, and wait until
            it does. */
         contmgr.other_pseg->pub.nursery_end = abort_category;
+        if (kind == WRITE_WRITE_CONTENTION) {
+            //marker_fetch_obj_write(contmgr.other_pseg->pub.segment_num,
+            //                       obj, contmgr.other_pseg->...);
+        }
 
         int sp = contmgr.other_pseg->safe_point;
         switch (sp) {
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -174,7 +174,7 @@
     /* Temporarily stores the marker information */
     char marker_self[_STM_MARKER_LEN];
     char marker_other[_STM_MARKER_LEN];
-    uintptr_t marker_inev[2];
+    uintptr_t marker_inev[2];  /* marker where this thread became inevitable */
 };
 
 enum /* safe_point */ {
diff --git a/c7/stm/marker.c b/c7/stm/marker.c
--- a/c7/stm/marker.c
+++ b/c7/stm/marker.c
@@ -32,10 +32,9 @@
 static void marker_expand(uintptr_t marker[2], char *segment_base,
                           char *outmarker)
 {
+    outmarker[0] = 0;
     if (marker[0] == 0)
         return;   /* no marker entry found */
-    if (outmarker[0] != 0)
-        return;   /* already collected an entry */
     if (stmcb_expand_marker != NULL) {
         stmcb_expand_marker(segment_base, marker[0], (object_t *)marker[1],
                             outmarker, _STM_MARKER_LEN);
@@ -44,9 +43,13 @@
 
 static void marker_fetch_expand(struct stm_priv_segment_info_s *pseg)
 {
+    if (pseg->marker_self[0] != 0)
+        return;   /* already collected an entry */
+
     uintptr_t marker[2];
     marker_fetch(pseg->pub.running_thread, marker);
     marker_expand(marker, pseg->pub.segment_base, pseg->marker_self);
+    pseg->marker_other[0] = 0;
 }
 
 char *_stm_expand_marker(void)
@@ -85,33 +88,11 @@
     pseg->marker_other[0] = 0;
 }
 
-static void marker_lookup_from_thread(struct stm_priv_segment_info_s *pseg,
-                                      object_t *obj, char *outmarker)
+static void marker_fetch_obj_write(uint8_t in_segment_num, object_t *obj,
+                                   uintptr_t marker[2])
 {
-    outmarker[0] = 0;
-
-    long i;
-    struct list_s *mlst = pseg->modified_old_objects;
-    struct list_s *mlstm = pseg->modified_old_objects_markers;
-    for (i = list_count(mlst); --i >= 0; ) {
-        if (list_item(mlst, i) == (uintptr_t)obj) {
-            uintptr_t marker[2];
-            assert(list_count(mlstm) == 2 * list_count(mlst));
-            marker[0] = list_item(mlstm, i * 2 + 0);
-            marker[1] = list_item(mlstm, i * 2 + 1);
-
-            marker_expand(marker, pseg->pub.segment_base, outmarker);
-            break;
-        }
-    }
-}
-
-static void marker_lookup_other_thread_write_write(uint8_t other_segment_num,
-                                                   object_t *obj)
-{
-    struct stm_priv_segment_info_s *my_pseg, *other_pseg;
-    char *other_segment_base = get_segment_base(other_segment_num);
-    acquire_segment_lock(other_segment_base);
+    char *segment_base = get_segment_base(in_segment_num);
+    acquire_segment_lock(segment_base);
     assert(_has_mutex());
 
     /* here, we acquired the other thread's segment_lock, which means that:
@@ -122,12 +103,35 @@
        (2) it is not mutating 'modified_old_objects' right now (we have
            the global mutex_lock at this point too).
     */
+    long i;
+    struct stm_priv_segment_info_s *pseg = get_priv_segment(in_segment_num);
+    struct list_s *mlst = pseg->modified_old_objects;
+    struct list_s *mlstm = pseg->modified_old_objects_markers;
+    for (i = list_count(mlst); --i >= 0; ) {
+        if (list_item(mlst, i) == (uintptr_t)obj) {
+            assert(list_count(mlstm) == 2 * list_count(mlst));
+            marker[0] = list_item(mlstm, i * 2 + 0);
+            marker[1] = list_item(mlstm, i * 2 + 1);
+            goto done;
+        }
+    }
+    marker[0] = 0;
+    marker[1] = 0;
+ done:
+    release_segment_lock(segment_base);
+}
+
+static void marker_lookup_other_thread_write_write(uint8_t other_segment_num,
+                                                   object_t *obj)
+{
+    uintptr_t marker[2];
+    marker_fetch_obj_write(other_segment_num, obj, marker);
+
+    struct stm_priv_segment_info_s *my_pseg, *other_pseg;
+    other_pseg = get_priv_segment(other_segment_num);
     my_pseg = get_priv_segment(STM_SEGMENT->segment_num);
-    other_pseg = get_priv_segment(other_segment_num);
-
-    marker_lookup_from_thread(other_pseg, obj, my_pseg->marker_other);
-
-    release_segment_lock(other_segment_base);
+    my_pseg->marker_other[0] = 0;
+    marker_expand(marker, other_pseg->pub.segment_base, my_pseg->marker_other);
 }
 
 static void marker_lookup_other_thread_inev(uint8_t other_segment_num)
@@ -144,10 +148,14 @@
 
 static void marker_lookup_same_thread_write_read(object_t *obj)
 {
+    uintptr_t marker[2];
+    marker_fetch_obj_write(STM_SEGMENT->segment_num, obj, marker);
+
     struct stm_priv_segment_info_s *my_pseg;
-
     my_pseg = get_priv_segment(STM_SEGMENT->segment_num);
-    marker_lookup_from_thread(my_pseg, obj, my_pseg->marker_self);
+    my_pseg->marker_self[0] = 0;
+    my_pseg->marker_other[0] = 0;
+    marker_expand(marker, STM_SEGMENT->segment_base, my_pseg->marker_self);
 }
 
 static void marker_fetch_inev(void)
diff --git a/c7/stm/marker.h b/c7/stm/marker.h
--- a/c7/stm/marker.h
+++ b/c7/stm/marker.h
@@ -6,6 +6,8 @@
 static void marker_copy(stm_thread_local_t *tl,
                         struct stm_priv_segment_info_s *pseg,
                         enum stm_time_e attribute_to, double time);
+static void marker_fetch_obj_write(uint8_t in_segment_num, object_t *obj,
+                                   uintptr_t marker[2]);
 static void marker_lookup_other_thread_write_write(uint8_t other_segment_num,
                                                    object_t *obj);
 static void marker_lookup_other_thread_inev(uint8_t other_segment_num);
diff --git a/c7/test/test_marker.py b/c7/test/test_marker.py
--- a/c7/test/test_marker.py
+++ b/c7/test/test_marker.py
@@ -159,7 +159,7 @@
         @ffi.callback("void(char *, uintptr_t, object_t *, char *, size_t)")
         def expand_marker(base, number, ptr, outbuf, outbufsize):
             seen.append(number)
-            s = '%d %r\x00' % (number, ptr)
+            s = '%d %r\x00' % (number, ptr == ffi.NULL)
             assert len(s) <= outbufsize
             outbuf[0:len(s)] = s
         seen = []
@@ -172,7 +172,7 @@
         self.push_root(ffi.cast("object_t *", 29))
         self.push_root(ffi.cast("object_t *", ffi.NULL))
         raw = lib._stm_expand_marker()
-        assert ffi.string(raw).startswith('29 ')
+        assert ffi.string(raw) == '29 True'
         assert seen == [29]
 
     def test_double_abort_markers_cb_write_write(self):
@@ -192,6 +192,7 @@
         self.pop_root()
         self.push_root(ffi.cast("object_t *", 17))
         self.push_root(ffi.cast("object_t *", ffi.NULL))
+        stm_minor_collect()
         #
         self.switch(1)
         self.start_transaction()
@@ -220,6 +221,7 @@
         self.pop_root()
         self.push_root(ffi.cast("object_t *", 17))
         self.push_root(ffi.cast("object_t *", ffi.NULL))
+        stm_minor_collect()
         #
         self.switch(1)
         self.start_transaction()
@@ -259,3 +261,41 @@
         assert tl.longest_marker_state == lib.STM_TIME_RUN_ABORTED_WRITE_READ
         assert ffi.string(tl.longest_marker_self) == '19'
         assert ffi.string(tl.longest_marker_other) == ''
+
+    def test_double_remote_markers_cb_write_write(self):
+        @ffi.callback("void(char *, uintptr_t, object_t *, char *, size_t)")
+        def expand_marker(base, number, ptr, outbuf, outbufsize):
+            s = '%d\x00' % (number,)
+            assert len(s) <= outbufsize
+            outbuf[0:len(s)] = s
+        lib.stmcb_expand_marker = expand_marker
+        p = stm_allocate_old(16)
+        #
+        self.start_transaction()
+        self.push_root(ffi.cast("object_t *", 19))
+        self.push_root(ffi.cast("object_t *", ffi.NULL))
+        stm_set_char(p, 'A')
+        self.pop_root()
+        self.pop_root()
+        self.push_root(ffi.cast("object_t *", 17))
+        self.push_root(ffi.cast("object_t *", ffi.NULL))
+        tl0 = self.get_stm_thread_local()
+        #
+        self.switch(1)
+        self.start_transaction()
+        self.become_inevitable()
+        self.push_root(ffi.cast("object_t *", 21))
+        self.push_root(ffi.cast("object_t *", ffi.NULL))
+        stm_set_char(p, 'B')    # aborts in #0
+        self.pop_root()
+        self.pop_root()
+        self.push_root(ffi.cast("object_t *", 23))
+        self.push_root(ffi.cast("object_t *", ffi.NULL))
+        #
+        py.test.raises(Conflict, self.switch, 0)
+        #
+        tl = self.get_stm_thread_local()
+        assert tl is tl0
+        assert tl.longest_marker_state == lib.STM_TIME_RUN_ABORTED_WRITE_WRITE
+        assert ffi.string(tl.longest_marker_self) == '19'
+        assert ffi.string(tl.longest_marker_other) == '21'


More information about the pypy-commit mailing list