[pypy-commit] stmgc default: Step 1 is to force minor collections to occur in all segments.

arigo noreply at buildbot.pypy.org
Thu Feb 27 20:51:52 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r901:160d2a6843f3
Date: 2014-02-27 20:51 +0100
http://bitbucket.org/pypy/stmgc/changeset/160d2a6843f3/

Log:	Step 1 is to force minor collections to occur in all segments.

diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -138,8 +138,15 @@
 
 static void major_collection_now_at_safe_point(void)
 {
+    dprintf((" .----- major_collection_now_at_safe_point -----\n"));
     assert(_has_mutex());
 
+    /* first, force a minor collection in each of the other segments */
+    major_do_minor_collections();
+
+    dprintf((" | used before collection: %ld\n",
+             (long)pages_ctl.total_allocated));
+
     fprintf(stderr, "hi, I should be doing a major GC here\n");
 
     reset_major_collection_requested();
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -231,21 +231,18 @@
     }
 }
 
-static void minor_collection(bool commit)
+#define MINOR_NOTHING_TO_DO(pseg)                                       \
+    ((pseg)->pub.nursery_current == (stm_char *)_stm_nursery_start &&   \
+     tree_is_cleared((pseg)->young_outside_nursery))
+
+
+static void _do_minor_collection(bool commit)
 {
-    assert(!_has_mutex());
-
-    stm_safe_point();
-    abort_if_needed();
-
     /* We must move out of the nursery any object found within the
        nursery.  All objects touched are either from the current
        transaction, or are from 'modified_old_objects'.  In all cases,
        we should only read and change objects belonging to the current
        segment.
-
-       XXX improve: it might be possible to run this function in
-       a safe-point but without the mutex, if we are careful
     */
 
     dprintf(("minor_collection commit=%d\n", (int)commit));
@@ -277,9 +274,20 @@
 
     throw_away_nursery();
 
+    assert(MINOR_NOTHING_TO_DO(STM_PSEGMENT));
     assert(list_is_empty(STM_PSEGMENT->objects_pointing_to_nursery));
 }
 
+static void minor_collection(bool commit)
+{
+    assert(!_has_mutex());
+
+    stm_safe_point();
+    abort_if_needed();
+
+    _do_minor_collection(commit);
+}
+
 void stm_collect(long level)
 {
     if (level > 0)
@@ -364,3 +372,24 @@
     }
 #endif
 }
+
+static void major_do_minor_collections(void)
+{
+    int original_num = STM_SEGMENT->segment_num;
+    long i;
+
+    for (i = 0; i < NB_SEGMENTS; i++) {
+        struct stm_priv_segment_info_s *pseg = get_priv_segment(i);
+        if (MINOR_NOTHING_TO_DO(pseg))  /*TS_NONE segments have NOTHING_TO_DO*/
+            continue;
+
+        assert(pseg->transaction_state != TS_NONE);
+        assert(pseg->safe_point == SP_SAFE_POINT);
+
+        set_gs_register(get_segment_base(i));
+        _do_minor_collection(/*commit=*/ false);
+        assert(MINOR_NOTHING_TO_DO(pseg));
+    }
+
+    set_gs_register(get_segment_base(original_num));
+}
diff --git a/c7/stm/nursery.h b/c7/stm/nursery.h
--- a/c7/stm/nursery.h
+++ b/c7/stm/nursery.h
@@ -8,3 +8,4 @@
 static void minor_collection(bool commit);
 static void check_nursery_at_transaction_start(void);
 static void throw_away_nursery(void);
+static void major_do_minor_collections(void);
diff --git a/c7/stm/sync.h b/c7/stm/sync.h
--- a/c7/stm/sync.h
+++ b/c7/stm/sync.h
@@ -19,6 +19,7 @@
 #ifndef NDEBUG
 static bool _has_mutex(void);
 #endif
+static void set_gs_register(char *value);
 
 /* acquire and release one of the segments for running the given thread
    (must have the mutex acquired!) */
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -342,6 +342,9 @@
 def stm_minor_collect():
     lib.stm_collect(0)
 
+def stm_major_collect():
+    lib.stm_collect(1)
+
 def stm_get_page_flag(pagenum):
     return lib._stm_get_page_flag(pagenum)
 
diff --git a/c7/test/test_gcpage.py b/c7/test/test_gcpage.py
--- a/c7/test/test_gcpage.py
+++ b/c7/test/test_gcpage.py
@@ -87,3 +87,18 @@
 
         assert stm_get_page_flag(stm_get_obj_pages(newer)[0]) == SHARED_PAGE
         assert stm_get_flags(newer) & GCFLAG_WRITE_BARRIER
+
+    def test_major_collection(self):
+        self.start_transaction()
+        new = stm_allocate(5000)
+        self.push_root(new)
+        stm_minor_collect()
+        assert 5000 <= lib._stm_total_allocated() <= 8192
+
+        self.pop_root()
+        stm_minor_collect()
+        assert 5000 <= lib._stm_total_allocated() <= 8192
+
+        stm_major_collect()
+        py.test.skip("in-progress")
+        assert lib._stm_total_allocated() == 0


More information about the pypy-commit mailing list