Author: Remi Meier <[email protected]>
Branch: stmgc-c8
Changeset: r80728:baa17f78bbb4
Date: 2015-11-17 13:25 +0100
http://bitbucket.org/pypy/pypy/changeset/baa17f78bbb4/

Log:    workaround for the JIT not emitting DETACH/REATTACH

        _build_stm_enter_leave_transactional_zone_helpers does not emit
        DETACH/REATTACH events to the log in all cases. This patch tries to
        detect such a situation and approximates the REATTACH event when it
        finds a minor gc going on. The reverse situation (no DETACH, but
        REATTACH) is probably possible too, but not handled here. A real
        solution is still needed.

diff --git a/pypy/stm/plot_stm_log.py b/pypy/stm/plot_stm_log.py
--- a/pypy/stm/plot_stm_log.py
+++ b/pypy/stm/plot_stm_log.py
@@ -88,7 +88,9 @@
         "\n".join(tr.info))
     assert inited is not None
 
-    if inevitabled is not None:
+    if inevitabled is not None and not aborted:
+        # we may still be "aborted" if we aborted when
+        # we tried to become inevitable (XXX)
         add_box(boxes, inited, inevitabled,
                 'becoming inevitable', info)
         add_box(boxes, inevitabled, ended,
@@ -125,6 +127,7 @@
         self.inevitabled = None
 
 
+
 def transaction_start(curr_trs, entry):
     if entry.threadnum in curr_trs:
         print "WARNING: Start of transaction while there is one already 
running"
@@ -153,11 +156,15 @@
 
         if entry.event == psl.STM_TRANSACTION_START:
             transaction_start(curr_trs, entry)
-        elif entry.event == psl.STM_TRANSACTION_REATTACH:
-            transaction_start(curr_trs, entry) # for now
+        elif entry.event == psl.STM_TRANSACTION_DETACH:
+            transaction_commit(curr_trs, finished_trs, entry)
+        elif (entry.event == psl.STM_TRANSACTION_REATTACH
+              or (entry.event == psl.STM_GC_MINOR_START
+                  and curr_trs.get(th_num) is None)):
+            # minor GC is approximate fix for JIT not emitting REATTACH
+            # in certain situations:
+            transaction_start(curr_trs, entry)
             transaction_become_inevitable(curr_trs, entry)
-        elif entry.event == psl.STM_TRANSACTION_DETACH:
-            transaction_commit(curr_trs, finished_trs, entry) # for now
         elif entry.event == psl.STM_TRANSACTION_COMMIT:
             transaction_commit(curr_trs, finished_trs, entry)
         elif entry.event == psl.STM_BECOME_INEVITABLE:
diff --git a/pypy/stm/print_stm_log.py b/pypy/stm/print_stm_log.py
--- a/pypy/stm/print_stm_log.py
+++ b/pypy/stm/print_stm_log.py
@@ -8,6 +8,9 @@
 STM_TRANSACTION_COMMIT  = 1
 STM_TRANSACTION_ABORT   = 2
 
+# sometimes there is a DETACH w/o REATTACH and the other way around.
+# This happens because the JIT does not emit DETACH/REATTACH events
+# to the log (XXX).
 STM_TRANSACTION_DETACH = 3
 STM_TRANSACTION_REATTACH = 4
 
@@ -114,7 +117,9 @@
         self._transaction_pause_time = 0.0
         self._transaction_aborting = False
         self._transaction_inev = None
+        self._transaction_detached_time = 0.0
         self._in_minor_coll = None
+        assert self._prev[1] == "stop"
 
     def transaction_start(self, entry):
         self.reset_counters()
@@ -128,8 +133,24 @@
             self._transaction_cpu_time += add_time
         elif prev_state == "pause":
             self._transaction_pause_time += add_time
+        elif prev_state == "detached":
+            self._transaction_detached_time += add_time
         self._prev = now, new_state
 
+    def make_sure_not_detached(self, entry):
+        # since some DETACH events are not followed by a REATTACH
+        # (because the JIT does not emit them), approximate by
+        # calling this method where we are sure that we shouldn't
+        # be detached.
+        if self._prev[1] == "detached":
+            self.progress(entry.timestamp, "run")
+
+    def transaction_detach(self, entry):
+        self.progress(entry.timestamp, "detached")
+
+    def transaction_reattach(self, entry):
+        self.progress(entry.timestamp, "run")
+
     def transaction_commit(self, entry):
         assert not self._transaction_aborting
         self.progress(entry.timestamp, "stop")
@@ -189,6 +210,7 @@
         c.paused_time += wait_time
 
     def gc_minor_start(self, event):
+        self.make_sure_not_detached(event)
         self._in_minor_coll = event.timestamp
 
     def gc_minor_done(self, event):
@@ -276,9 +298,9 @@
         if entry.event == STM_TRANSACTION_START:
             t.transaction_start(entry)
         elif entry.event == STM_TRANSACTION_DETACH:
-            t.transaction_commit(entry) # for now
+            t.transaction_detach(entry)
         elif entry.event == STM_TRANSACTION_REATTACH:
-            t.transaction_start(entry) # for now
+            t.transaction_reattach(entry)
             t.become_inevitable(entry)
         elif entry.event == STM_TRANSACTION_COMMIT:
             t.transaction_commit(entry)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to