Author: Armin Rigo <ar...@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' _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit