[pypy-commit] pypy stmgc-c8: import stmgc-c8 f6788cf5fb73
Raemi
noreply at buildbot.pypy.org
Mon Mar 30 13:52:28 CEST 2015
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: stmgc-c8
Changeset: r76637:ddeaa80c4bf7
Date: 2015-03-30 10:55 +0200
http://bitbucket.org/pypy/pypy/changeset/ddeaa80c4bf7/
Log: import stmgc-c8 f6788cf5fb73
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 @@
-b548b42c978e+
+f6788cf5fb73
diff --git a/rpython/translator/stm/src_stm/stm/atomic.h b/rpython/translator/stm/src_stm/stm/atomic.h
--- a/rpython/translator/stm/src_stm/stm/atomic.h
+++ b/rpython/translator/stm/src_stm/stm/atomic.h
@@ -27,13 +27,11 @@
# define HAVE_FULL_EXCHANGE_INSN
static inline void spin_loop(void) { asm("pause" : : : "memory"); }
static inline void write_fence(void) { asm("" : : : "memory"); }
- static inline void read_fence(void) { asm("" : : : "memory"); }
#else
static inline void spin_loop(void) { asm("" : : : "memory"); }
static inline void write_fence(void) { __sync_synchronize(); }
- static inline void read_fence(void) { asm("" : : : "memory"); }
#endif
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
@@ -2,6 +2,11 @@
#ifndef _STM_CORE_H_
# error "must be compiled via stmgc.c"
#endif
+char *stm_object_pages;
+long _stm_segment_nb_pages = NB_PAGES;
+int _stm_nb_segments = NB_SEGMENTS;
+int _stm_psegment_ofs = (int)(uintptr_t)STM_PSEGMENT;
+
/* *** MISC *** */
static void free_bk(struct stm_undo_s *undo)
{
@@ -48,6 +53,7 @@
assert(IMPLY(from_segnum >= 0, get_priv_segment(from_segnum)->modification_lock));
assert(STM_PSEGMENT->modification_lock);
+ long my_segnum = STM_SEGMENT->segment_num;
DEBUG_EXPECT_SEGFAULT(false);
for (; undo < end; undo++) {
if (undo->type == TYPE_POSITION_MARKER)
@@ -57,18 +63,19 @@
uintptr_t current_page_num = ((uintptr_t)oslice) / 4096;
if (pagenum == -1) {
- if (get_page_status_in(STM_SEGMENT->segment_num,
- current_page_num) == PAGE_NO_ACCESS)
+ if (get_page_status_in(my_segnum, current_page_num) == PAGE_NO_ACCESS)
continue;
- }
- else {
- if (current_page_num != pagenum)
- continue;
+ } else if (pagenum != current_page_num) {
+ continue;
}
- if (from_segnum == -2 && _stm_was_read(obj) && (obj->stm_flags & GCFLAG_WB_EXECUTED)) {
+ if (from_segnum == -2
+ && _stm_was_read(obj)
+ && (get_page_status_in(my_segnum, (uintptr_t)obj / 4096) == PAGE_ACCESSIBLE)
+ && (obj->stm_flags & GCFLAG_WB_EXECUTED)) {
/* called from stm_validate():
> if not was_read(), we certainly didn't modify
+ > if obj->stm_flags is not accessible, WB_EXECUTED cannot be set
> if not WB_EXECUTED, we may have read from the obj in a different page but
did not modify it (should not occur right now, but future proof!)
only the WB_EXECUTED alone is not enough, since we may have imported from a
@@ -79,8 +86,7 @@
/* XXX: if the next assert is always true, we should never get a segfault
in this function at all. So the DEBUG_EXPECT_SEGFAULT is correct. */
- assert((get_page_status_in(STM_SEGMENT->segment_num,
- current_page_num) != PAGE_NO_ACCESS));
+ assert((get_page_status_in(my_segnum, current_page_num) != PAGE_NO_ACCESS));
/* dprintf(("import slice seg=%d obj=%p off=%lu sz=%d pg=%lu\n", */
/* from_segnum, obj, SLICE_OFFSET(undo->slice), */
@@ -95,7 +101,8 @@
if (src_segment_base == NULL && SLICE_OFFSET(undo->slice) == 0) {
/* check that restored obj doesn't have WB_EXECUTED */
- assert(!(obj->stm_flags & GCFLAG_WB_EXECUTED));
+ assert((get_page_status_in(my_segnum, (uintptr_t)obj / 4096) == PAGE_NO_ACCESS)
+ || !(obj->stm_flags & GCFLAG_WB_EXECUTED));
}
}
DEBUG_EXPECT_SEGFAULT(true);
@@ -1107,16 +1114,6 @@
STM_PSEGMENT->shadowstack_at_start_of_transaction = tl->shadowstack;
STM_PSEGMENT->threadlocal_at_start_of_transaction = tl->thread_local_obj;
- enter_safe_point_if_requested();
- dprintf(("> start_transaction\n"));
-
- s_mutex_unlock(); // XXX it's probably possible to not acquire this here
-
- uint8_t old_rv = STM_SEGMENT->transaction_read_version;
- STM_SEGMENT->transaction_read_version = old_rv + 1;
- if (UNLIKELY(old_rv == 0xff)) {
- reset_transaction_read_version();
- }
assert(list_is_empty(STM_PSEGMENT->modified_old_objects));
assert(list_is_empty(STM_PSEGMENT->large_overflow_objects));
@@ -1135,6 +1132,25 @@
check_nursery_at_transaction_start();
+ /* Change read-version here, because if we do stm_validate in the
+ safe-point below, we should not see our old reads from the last
+ transaction. */
+ uint8_t rv = STM_SEGMENT->transaction_read_version;
+ if (rv < 0xff) /* else, rare (maybe impossible?) case: we did already */
+ rv++; /* incr it but enter_safe_point_if_requested() aborted */
+ STM_SEGMENT->transaction_read_version = rv;
+
+ /* Warning: this safe-point may run light finalizers and register
+ commit/abort callbacks if a major GC is triggered here */
+ enter_safe_point_if_requested();
+ dprintf(("> start_transaction\n"));
+
+ s_mutex_unlock(); // XXX it's probably possible to not acquire this here
+
+ if (UNLIKELY(rv == 0xff)) {
+ reset_transaction_read_version();
+ }
+
stm_validate();
}
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
@@ -222,11 +222,10 @@
static void free_cle(struct stm_commit_log_entry_s *e);
-#ifndef STM_TESTS
-static char *stm_object_pages;
-#else
-char *stm_object_pages;
-#endif
+extern char *stm_object_pages;
+extern long _stm_segment_nb_pages;
+extern int _stm_nb_segments;
+extern int _stm_psegment_ofs;
static stm_thread_local_t *stm_all_thread_locals = NULL;
diff --git a/rpython/translator/stm/src_stm/stm/nursery.c b/rpython/translator/stm/src_stm/stm/nursery.c
--- a/rpython/translator/stm/src_stm/stm/nursery.c
+++ b/rpython/translator/stm/src_stm/stm/nursery.c
@@ -461,16 +461,20 @@
}
OPT_ASSERT((nursery_used & 7) == 0);
-
-#if _STM_NURSERY_ZEROED
+#ifndef NDEBUG
/* reset the nursery by zeroing it */
char *realnursery;
realnursery = REAL_ADDRESS(pseg->pub.segment_base, _stm_nursery_start);
+#if _STM_NURSERY_ZEROED
memset(realnursery, 0, nursery_used);
/* assert that the rest of the nursery still contains only zeroes */
assert_memset_zero(realnursery + nursery_used,
(NURSERY_END - _stm_nursery_start) - nursery_used);
+
+#else
+ memset(realnursery, 0xa0, nursery_used);
+#endif
#endif
pseg->pub.nursery_current = (stm_char *)_stm_nursery_start;
@@ -636,6 +640,11 @@
#if _STM_NURSERY_ZEROED
memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0, size_rounded_up);
#else
+
+#ifndef NDEBUG
+ memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0xb0, size_rounded_up);
+#endif
+
o->stm_flags = 0;
/* make all pages of 'o' accessible as synchronize_obj_flush() in minor
collections assumes all young objs are fully accessible. */
diff --git a/rpython/translator/stm/src_stm/stm/sync.c b/rpython/translator/stm/src_stm/stm/sync.c
--- a/rpython/translator/stm/src_stm/stm/sync.c
+++ b/rpython/translator/stm/src_stm/stm/sync.c
@@ -103,6 +103,24 @@
/************************************************************/
+void stm_wait_for_current_inevitable_transaction(void)
+{
+ struct stm_commit_log_entry_s *current = STM_PSEGMENT->last_commit_log_entry;
+
+ /* XXX: don't do busy-waiting */
+ while (1) {
+ if (current->next == NULL) {
+ break;
+ } else if (current->next == INEV_RUNNING) {
+ usleep(10);
+ continue;
+ }
+ current = current->next;
+ }
+}
+
+
+
static bool acquire_thread_segment(stm_thread_local_t *tl)
{
/* This function acquires a segment for the currently running thread,
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
@@ -304,6 +304,11 @@
void stm_start_inevitable_transaction(stm_thread_local_t *tl);
void stm_commit_transaction(void);
+
+/* Temporary fix? Call this outside a transaction. If there is an
+ inevitable transaction running somewhere else, wait until it finishes. */
+void stm_wait_for_current_inevitable_transaction(void);
+
void stm_abort_transaction(void) __attribute__((noreturn));
void stm_collect(long level);
More information about the pypy-commit
mailing list