Commits

Remi Meier committed d483af7

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

Comments (0)

Files changed (8)

rpython/jit/backend/x86/assembler.py

                                 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)
                               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:
             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:

rpython/jit/backend/x86/runner.py

 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
 
     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)
             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,

rpython/memory/gctransform/stmframework.py

         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
 

rpython/rlib/rstm.py

     llop.stm_become_inevitable(lltype.Void)
 
 @dont_look_inside
+def stop_all_other_threads():
+    llop.stm_stop_all_other_threads(lltype.Void)
+
+@dont_look_inside
+def partial_commit_and_resume_other_threads():
+    llop.stm_partial_commit_and_resume_other_threads(lltype.Void)
+    
+@dont_look_inside
 def should_break_transaction():
     return we_are_translated() and (
         llop.stm_should_break_transaction(lltype.Bool))

rpython/rtyper/llinterp.py

     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

rpython/rtyper/lltypesystem/lloperation.py

     '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),

rpython/translator/c/funcgen.py

     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

rpython/translator/stm/funcgen.py

     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,)