[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