[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