[pypy-commit] pypy stmgc-c4: atomically patch assembler by stopping & aborting all other transactions

Raemi noreply at buildbot.pypy.org
Mon Nov 4 13:20:34 CET 2013


Author: Remi Meier <remi.meier at gmail.com>
Branch: stmgc-c4
Changeset: r67830:d483af75a05b
Date: 2013-11-04 13:18 +0100
http://bitbucket.org/pypy/pypy/changeset/d483af75a05b/

Log:	atomically patch assembler by stopping & aborting all other
	transactions during raw patching.

diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -770,8 +770,6 @@
                                 rawstart)
         debug_bridge(descr_number, rawstart, codeendpos)
         self.patch_pending_failure_recoveries(rawstart)
-        # patch the jump from original guard
-        self.patch_jump_for_descr(faildescr, rawstart)
         ops_offset = self.mc.ops_offset
         frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
                           frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
@@ -780,6 +778,14 @@
                               ops_offset=ops_offset, descr=faildescr)
         self.fixup_target_tokens(rawstart)
         self.update_frame_depth(frame_depth)
+
+        if self.cpu.gc_ll_descr.stm:
+            rstm.stop_all_other_threads()
+        # patch the jump from original guard after the frame-depth update
+        self.patch_jump_for_descr(faildescr, rawstart)
+        if self.cpu.gc_ll_descr.stm:
+            rstm.partial_commit_and_resume_other_threads()
+        
         self.teardown()
         # oprofile support
         if self.cpu.profile_agent is not None:
@@ -1082,7 +1088,13 @@
             assert mc.get_relative_pos() == 5
         else:
             assert mc.get_relative_pos() <= 13
+        # patch assembler:
+        if self.cpu.gc_ll_descr.stm:
+            rstm.stop_all_other_threads()
         mc.copy_to_raw_memory(oldadr)
+        if self.cpu.gc_ll_descr.stm:
+            rstm.partial_commit_and_resume_other_threads()
+        
 
     def dump(self, text):
         if not self.verbose:
diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py
--- a/rpython/jit/backend/x86/runner.py
+++ b/rpython/jit/backend/x86/runner.py
@@ -7,6 +7,7 @@
 from rpython.jit.backend.x86.profagent import ProfileAgent
 from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU
 from rpython.jit.backend.x86 import regloc
+from rpython.rlib import rstm
 
 import sys
 
@@ -127,6 +128,9 @@
     def invalidate_loop(self, looptoken):
         from rpython.jit.backend.x86 import codebuf
 
+        if self.gc_ll_descr.stm:
+            rstm.stop_all_other_threads()
+            
         for addr, tgt in looptoken.compiled_loop_token.invalidate_positions:
             mc = codebuf.MachineCodeBlockWrapper()
             mc.JMP_l(tgt)
@@ -134,6 +138,9 @@
             mc.copy_to_raw_memory(addr - 1)
         # positions invalidated
         looptoken.compiled_loop_token.invalidate_positions = []
+        
+        if self.gc_ll_descr.stm:
+            rstm.partial_commit_and_resume_other_threads()
 
     def get_all_loop_runs(self):
         l = lltype.malloc(LOOP_RUN_CONTAINER,
diff --git a/rpython/memory/gctransform/stmframework.py b/rpython/memory/gctransform/stmframework.py
--- a/rpython/memory/gctransform/stmframework.py
+++ b/rpython/memory/gctransform/stmframework.py
@@ -98,6 +98,8 @@
         self.pop_roots(hop, livevars)
 
     gct_stm_become_inevitable   = _gct_with_roots_pushed
+    gct_stm_stop_all_other_threads   = _gct_with_roots_pushed
+    gct_stm_partial_commit_and_resume_other_threads  = _gct_with_roots_pushed
     gct_stm_perform_transaction = _gct_with_roots_pushed
     gct_stm_allocate_nonmovable_int_adr = _gct_with_roots_pushed
 
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -34,6 +34,14 @@
     llop.stm_become_inevitable(lltype.Void)
 
 @dont_look_inside
+def stop_all_other_threads():
+    llop.stm_stop_all_other_threads(lltype.Void)
+
+ at dont_look_inside
+def partial_commit_and_resume_other_threads():
+    llop.stm_partial_commit_and_resume_other_threads(lltype.Void)
+    
+ at dont_look_inside
 def should_break_transaction():
     return we_are_translated() and (
         llop.stm_should_break_transaction(lltype.Bool))
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -977,6 +977,8 @@
     op_stm_major_collect = _stm_not_implemented
     op_stm_abort_and_retry = _stm_not_implemented
     op_stm_become_inevitable = _stm_not_implemented
+    op_stm_stop_all_other_threads = _stm_not_implemented
+    op_stm_partial_commit_and_resume_other_threads = _stm_not_implemented
 
     # __________________________________________________________
     # operations on addresses
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -416,6 +416,8 @@
     'stm_allocate':           LLOp(sideeffects=False, canmallocgc=True),
     'stm_allocate_nonmovable_int_adr': LLOp(sideeffects=False, canmallocgc=True),
     'stm_become_inevitable':  LLOp(canmallocgc=True),
+    'stm_stop_all_other_threads': LLOp(canmallocgc=True),
+    'stm_partial_commit_and_resume_other_threads': LLOp(canmallocgc=True),
     'stm_minor_collect':      LLOp(canmallocgc=True),
     'stm_major_collect':      LLOp(canmallocgc=True),
     'stm_get_tid':            LLOp(canfold=True),
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -586,6 +586,8 @@
     OP_STM_INITIALIZE                   = _OP_STM
     OP_STM_FINALIZE                     = _OP_STM
     OP_STM_BECOME_INEVITABLE            = _OP_STM
+    OP_STM_STOP_ALL_OTHER_THREADS       = _OP_STM
+    OP_STM_PARTIAL_COMMIT_AND_RESUME_OTHER_THREADS = _OP_STM
     OP_STM_BARRIER                      = _OP_STM
     OP_STM_PTR_EQ                       = _OP_STM
     OP_STM_PUSH_ROOT                    = _OP_STM
diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -103,6 +103,12 @@
     string_literal = c_string_constant(info)
     return 'stm_become_inevitable(%s);' % (string_literal,)
 
+def stm_stop_all_other_threads(funcgen, op):
+    return 'stm_stop_all_other_threads();'
+
+def stm_partial_commit_and_resume_other_threads(funcgen, op):
+    return 'stm_partial_commit_and_resume_other_threads();'
+
 def stm_push_root(funcgen, op):
     arg0 = funcgen.expr(op.args[0])
     return 'stm_push_root((gcptr)%s);' % (arg0,)


More information about the pypy-commit mailing list