[pypy-commit] stmgc queue: fix fix fix minor collections
arigo
noreply at buildbot.pypy.org
Thu Jun 18 23:24:56 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: queue
Changeset: r1871:0a5991d79ba3
Date: 2015-06-18 23:25 +0200
http://bitbucket.org/pypy/stmgc/changeset/0a5991d79ba3/
Log: fix fix fix minor collections
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -553,6 +553,9 @@
if (STM_PSEGMENT->finalizers != NULL)
collect_objs_still_young_but_with_finalizers();
+ if (STM_PSEGMENT->active_queues != NULL)
+ collect_active_queues();
+
collect_oldrefs_to_nursery();
assert(list_is_empty(STM_PSEGMENT->old_objects_with_cards_set));
diff --git a/c8/stm/queue.c b/c8/stm/queue.c
--- a/c8/stm/queue.c
+++ b/c8/stm/queue.c
@@ -210,13 +210,6 @@
entry->next = seg->added_in_this_transaction;
seg->added_in_this_transaction = entry;
seg->unfinished_tasks_in_this_transaction++;
-
- /* add qobj to 'objects_pointing_to_nursery' if it has the
- WRITE_BARRIER flag */
- if (qobj->stm_flags & GCFLAG_WRITE_BARRIER) {
- qobj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
- LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, qobj);
- }
}
static void queue_check_entry(queue_entry_t *entry)
@@ -381,14 +374,30 @@
}
queue_trace_list(queue->old_entries, trace, NULL);
}
- else {
- /* for minor collections: it is enough to trace the objects
- added in the current transaction. All other objects are
- old (or, worse, belong to a parallel thread and must not
- be traced). */
+ /* for minor collections, done differently.
+ see collect_active_queues() below */
+}
+
+static void collect_active_queues(void)
+{
+ wlog_t *item;
+ TREE_LOOP_FORWARD(STM_PSEGMENT->active_queues, item) {
+ /* it is enough to trace the objects added in the current
+ transaction. All other objects reachable from the queue
+ are old (or, worse, belong to a parallel thread and must
+ not be traced). Performance note: this is linear in the
+ total number of active queues, but at least each queue that
+ has not been touched for a while in a long transaction is
+ handled very cheaply.
+ */
+ stm_queue_t *queue = (stm_queue_t *)item->addr;
stm_queue_segment_t *seg = &queue->segs[STM_SEGMENT->segment_num - 1];
- queue_trace_list(seg->added_in_this_transaction, trace,
- seg->added_young_limit);
- seg->added_young_limit = seg->added_in_this_transaction;
- }
+ if (seg->added_young_limit != seg->added_in_this_transaction) {
+ dprintf(("minor collection trace queue %p\n", queue));
+ queue_trace_list(seg->added_in_this_transaction,
+ &minor_trace_if_young,
+ seg->added_young_limit);
+ seg->added_young_limit = seg->added_in_this_transaction;
+ }
+ } TREE_LOOP_END;
}
diff --git a/c8/stm/queue.h b/c8/stm/queue.h
--- a/c8/stm/queue.h
+++ b/c8/stm/queue.h
@@ -1,1 +1,2 @@
static void queues_deactivate_all(bool at_commit);
+static void collect_active_queues(void);
diff --git a/c8/test/test_queue.py b/c8/test/test_queue.py
--- a/c8/test/test_queue.py
+++ b/c8/test/test_queue.py
@@ -168,6 +168,7 @@
#
obj2 = stm_allocate(32)
stm_set_char(obj2, 'H')
+ print 'put2'
self.put(qobj, obj2)
stm_minor_collect()
obj2 = self.get(qobj)
More information about the pypy-commit
mailing list