Author: Remi Meier <[email protected]>
Branch:
Changeset: r1568:d24560f5557a
Date: 2015-01-21 17:26 +0100
http://bitbucket.org/pypy/stmgc/changeset/d24560f5557a/
Log: free the commit log as part of major gcs
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -154,7 +154,7 @@
size_t written_count;
struct stm_undo_s written[];
};
-static struct stm_commit_log_entry_s commit_log_root = {NULL, -1, 0, 0};
+static struct stm_commit_log_entry_s commit_log_root;
#ifndef STM_TESTS
diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -531,6 +531,52 @@
_stm_smallmalloc_sweep();
}
+static void clean_up_commit_log_entries()
+{
+ struct stm_commit_log_entry_s *cl, *next;
+
+#ifndef NDEBUG
+ /* check that all segments are at the same revision: */
+ cl = get_priv_segment(0)->last_commit_log_entry;
+ for (long i = 1; i < NB_SEGMENTS; i++) {
+ assert(get_priv_segment(i)->last_commit_log_entry == cl);
+ }
+#endif
+
+ /* if there is only one element, we don't have to do anything: */
+ cl = &commit_log_root;
+
+ if (cl->next == NULL || cl->next == INEV_RUNNING)
+ return;
+
+ bool was_inev = false;
+ uint64_t rev_num = -1;
+
+ next = cl->next; /* guaranteed to exist */
+ do {
+ cl = next;
+ rev_num = cl->rev_num;
+
+ next = cl->next;
+ free(cl);
+ if (next == INEV_RUNNING) {
+ was_inev = true;
+ break;
+ }
+ } while (next != NULL);
+
+ /* set the commit_log_root to the last, common cl entry: */
+ commit_log_root.next = was_inev ? INEV_RUNNING : NULL;
+ commit_log_root.rev_num = rev_num;
+
+ /* update in all segments: */
+ for (long i = 0; i < NB_SEGMENTS; i++) {
+ get_priv_segment(i)->last_commit_log_entry = &commit_log_root;
+ }
+
+ assert(_stm_count_cl_entries() == 0);
+}
+
static void major_collection_now_at_safe_point(void)
@@ -544,6 +590,12 @@
dprintf((" | used before collection: %ld\n",
(long)pages_ctl.total_allocated));
+ dprintf((" | commit log entries before: %ld\n",
+ _stm_count_cl_entries()));
+
+ /* free all commit log entries. all segments are on the most recent
+ revision now. */
+ clean_up_commit_log_entries();
/* only necessary because of assert that fails otherwise (XXX) */
acquire_all_privatization_locks();
@@ -558,10 +610,10 @@
mark_visit_from_roots();
LIST_FREE(marked_objects_to_trace);
- /* /\* cleanup *\/ */
+ /* cleanup */
clean_up_segment_lists();
- /* /\* sweeping *\/ */
+ /* sweeping */
sweep_large_objects();
sweep_small_objects();
diff --git a/c8/stm/misc.c b/c8/stm/misc.c
--- a/c8/stm/misc.c
+++ b/c8/stm/misc.c
@@ -41,6 +41,19 @@
return (obj->stm_flags & _STM_GCFLAG_WRITE_BARRIER) == 0;
}
+long _stm_count_cl_entries()
+{
+ struct stm_commit_log_entry_s *cl = &commit_log_root;
+
+ long count = 0;
+ while ((cl = cl->next)) {
+ if (cl == INEV_RUNNING)
+ break;
+ count++;
+ }
+ return count;
+}
+
#ifdef STM_TESTS
bool _stm_is_accessible_page(uintptr_t pagenum)
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -78,6 +78,11 @@
setup_protection_settings();
setup_signal_handler();
+ commit_log_root.next = NULL;
+ commit_log_root.segment_num = -1;
+ commit_log_root.rev_num = 0;
+ commit_log_root.written_count = 0;
+
long i;
/* including seg0 */
for (i = 0; i < NB_SEGMENTS; i++) {
@@ -129,6 +134,8 @@
need to call it. */
assert(!_has_mutex());
+ assert(commit_log_root.segment_num == -1);
+
long i;
for (i = 0; i < NB_SEGMENTS; i++) {
struct stm_priv_segment_info_s *pr = get_priv_segment(i);
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -113,6 +113,7 @@
object_t *_stm_enum_objects_pointing_to_nursery(long index);
object_t *_stm_next_last_cl_entry();
void _stm_start_enum_last_cl_entry();
+long _stm_count_cl_entries();
uint64_t _stm_total_allocated(void);
#endif
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -110,6 +110,7 @@
object_t *_stm_enum_objects_pointing_to_nursery(long index);
object_t *_stm_next_last_cl_entry();
void _stm_start_enum_last_cl_entry();
+long _stm_count_cl_entries();
void *memset(void *s, int c, size_t n);
@@ -435,6 +436,7 @@
def stm_major_collect():
res = lib._check_stm_collect(1)
+ assert count_commit_log_entries() == 0
if res == 1:
raise Conflict()
return res
@@ -474,7 +476,7 @@
return None
return map(lib._stm_enum_old_objects_with_cards, range(count))
-def last_commit_log_entries():
+def last_commit_log_entry_objs():
lib._stm_start_enum_last_cl_entry()
res = []
obj = lib._stm_next_last_cl_entry()
@@ -483,6 +485,9 @@
obj = lib._stm_next_last_cl_entry()
return res
+def count_commit_log_entries():
+ return lib._stm_count_cl_entries()
+
SHADOWSTACK_LENGTH = 1000
diff --git a/c8/test/test_basic.py b/c8/test/test_basic.py
--- a/c8/test/test_basic.py
+++ b/c8/test/test_basic.py
@@ -33,12 +33,14 @@
self.switch(1)
self.start_transaction()
self.commit_transaction()
- assert last_commit_log_entries() == []
+ assert last_commit_log_entry_objs() == []
+ assert count_commit_log_entries() == 1
self.switch(0)
self.commit_transaction()
- assert last_commit_log_entries() == []
+ assert last_commit_log_entry_objs() == []
+ assert count_commit_log_entries() == 2
def test_simple_read(self):
self.start_transaction()
@@ -46,7 +48,7 @@
stm_read(lp1)
assert stm_was_read(lp1)
self.commit_transaction()
- assert last_commit_log_entries() == []
+ assert last_commit_log_entry_objs() == []
def test_simple_write(self):
self.start_transaction()
@@ -57,7 +59,7 @@
assert modified_old_objects() == [] # object not old
assert objects_pointing_to_nursery() == [] # short transaction
self.commit_transaction()
- assert last_commit_log_entries() == []
+ assert last_commit_log_entry_objs() == []
def test_allocate_old(self):
lp1 = stm_allocate_old(16)
@@ -106,7 +108,7 @@
#
self.switch(1)
self.commit_transaction()
- assert last_commit_log_entries() == [lp1]
+ assert last_commit_log_entry_objs() == [lp1]
#
py.test.raises(Conflict, self.switch, 0) # detects rw conflict
@@ -128,13 +130,13 @@
#
self.switch(0)
self.commit_transaction()
- assert last_commit_log_entries() == [lp1] # commit '0'
+ assert last_commit_log_entry_objs() == [lp1] # commit '0'
#
py.test.raises(Conflict, self.switch, 1)
self.start_transaction() # updates to '0'
stm_set_char(lp1, 'x')
self.commit_transaction()
- assert last_commit_log_entries() == [lp1] # commit 'x'
+ assert last_commit_log_entry_objs() == [lp1] # commit 'x'
#
if only_bk:
self.start_transaction()
@@ -169,7 +171,7 @@
#
self.switch(1)
self.commit_transaction()
- assert last_commit_log_entries() == [lp1]
+ assert last_commit_log_entry_objs() == [lp1]
# '1' is committed
#
if only_bk:
@@ -206,13 +208,13 @@
#
self.switch(0)
self.commit_transaction()
- assert last_commit_log_entries() == [lp1] # commit '0'
+ assert last_commit_log_entry_objs() == [lp1] # commit '0'
#
py.test.raises(Conflict, self.switch, 1)
self.start_transaction() # updates to '0'
stm_set_char(lp1, 'x')
self.commit_transaction()
- assert last_commit_log_entries() == [lp1] # commit 'x'
+ assert last_commit_log_entry_objs() == [lp1] # commit 'x'
#
if only_bk:
self.start_transaction()
@@ -240,7 +242,7 @@
self.start_transaction()
stm_set_char(lp1, 'C')
self.commit_transaction()
- assert last_commit_log_entries() == [lp1] # commit 'C'
+ assert last_commit_log_entry_objs() == [lp1] # commit 'C'
#
if only_bk:
self.start_transaction()
@@ -270,7 +272,7 @@
self.start_transaction()
stm_set_char(lp2, 'C')
self.commit_transaction() # R1
- assert last_commit_log_entries() == [lp2] # commit 'C'
+ assert last_commit_log_entry_objs() == [lp2] # commit 'C'
if only_bk:
self.start_transaction()
stm_set_char(lp2, 'c') # R1.1
@@ -279,7 +281,7 @@
self.start_transaction()
stm_set_char(lp1, 'D')
self.commit_transaction() # R2
- assert last_commit_log_entries() == [lp1] # commit 'D'
+ assert last_commit_log_entry_objs() == [lp1] # commit 'D'
if only_bk:
self.start_transaction()
stm_set_char(lp1, 'd') # R2.1
@@ -309,13 +311,13 @@
self.start_transaction()
stm_set_char(lp2, 'C')
self.commit_transaction() # R1
- assert last_commit_log_entries() == [lp2] # commit 'C'
+ assert last_commit_log_entry_objs() == [lp2] # commit 'C'
#
self.switch(2)
self.start_transaction()
stm_set_char(lp1, 'D')
self.commit_transaction() # R2
- assert last_commit_log_entries() == [lp1] # commit 'D'
+ assert last_commit_log_entry_objs() == [lp1] # commit 'D'
#
self.switch(3)
self.start_transaction() # stm_validate() -> R2
@@ -325,13 +327,13 @@
self.start_transaction()
stm_set_char(lp1, 'I')
self.commit_transaction() # R2
- assert last_commit_log_entries() == [lp1] # commit 'I'
+ assert last_commit_log_entry_objs() == [lp1] # commit 'I'
#
self.switch(1)
self.start_transaction()
stm_set_char(lp2, 'H')
self.commit_transaction() # R3
- assert last_commit_log_entries() == [lp2] # commit 'H'
+ assert last_commit_log_entry_objs() == [lp2] # commit 'H'
#
self.switch(3, validate=False) # R2 again
assert stm_get_char(lp1) == 'D' # R2
@@ -353,7 +355,7 @@
self.start_transaction()
stm_set_char(lp1, 'C')
self.commit_transaction() # R1
- assert last_commit_log_entries() == [lp1] # commit 'C'
+ assert last_commit_log_entry_objs() == [lp1] # commit 'C'
self.start_transaction()
stm_set_char(lp1, 'c') # bk_copy
#
@@ -384,7 +386,7 @@
assert (p2 - p1) % 4096 == 0
assert stm_get_char(lp) == 'u'
self.commit_transaction()
- assert last_commit_log_entries() == [lp]
+ assert last_commit_log_entry_objs() == [lp]
def test_commit_fresh_objects2(self):
self.switch(1)
diff --git a/c8/test/test_gcpage.py b/c8/test/test_gcpage.py
--- a/c8/test/test_gcpage.py
+++ b/c8/test/test_gcpage.py
@@ -409,3 +409,26 @@
self.switch(1, False)
py.test.raises(Conflict, stm_major_collect)
+
+
+ def test_cleaning_of_cl(self):
+ self.start_transaction()
+ stm_major_collect()
+ self.commit_transaction()
+
+ self.switch(1)
+ self.start_transaction()
+ self.commit_transaction()
+
+ self.switch(0)
+ self.start_transaction()
+ assert count_commit_log_entries() == 2
+ stm_major_collect()
+ assert count_commit_log_entries() == 0
+
+ stm_major_collect()
+
+ self.become_inevitable()
+ stm_major_collect()
+ stm_major_collect()
+ self.commit_transaction()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit