[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