8201218: PPC64: Avoid use of yield instruction on spinlock
Reviewed-by: mdoerr, goetz
--- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp Tue Apr 10 09:12:23 2018 +0200
+++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp Thu Apr 05 20:09:33 2018 -0400
@@ -620,7 +620,7 @@
inline void Assembler::stqcx_(Register s, Register a, Register b) { emit_int32( STQCX_OPCODE | rs(s) | ra0mem(a) | rb(b) | rc(1)); }
// Instructions for adjusting thread priority
-// for simultaneous multithreading (SMT) on POWER5.
+// for simultaneous multithreading (SMT) on >= POWER5.
inline void Assembler::smt_prio_very_low() { Assembler::or_unchecked(R31, R31, R31); }
inline void Assembler::smt_prio_low() { Assembler::or_unchecked(R1, R1, R1); }
inline void Assembler::smt_prio_medium_low() { Assembler::or_unchecked(R6, R6, R6); }
@@ -628,11 +628,11 @@
inline void Assembler::smt_prio_medium_high() { Assembler::or_unchecked(R5, R5, R5); }
inline void Assembler::smt_prio_high() { Assembler::or_unchecked(R3, R3, R3); }
// >= Power7
-inline void Assembler::smt_yield() { Assembler::or_unchecked(R27, R27, R27); }
-inline void Assembler::smt_mdoio() { Assembler::or_unchecked(R29, R29, R29); }
-inline void Assembler::smt_mdoom() { Assembler::or_unchecked(R30, R30, R30); }
-// >= Power8
-inline void Assembler::smt_miso() { Assembler::or_unchecked(R26, R26, R26); }
+inline void Assembler::smt_yield() { Assembler::or_unchecked(R27, R27, R27); } // never actually implemented
+inline void Assembler::smt_mdoio() { Assembler::or_unchecked(R29, R29, R29); } // never actually implemetned
+inline void Assembler::smt_mdoom() { Assembler::or_unchecked(R30, R30, R30); } // never actually implemented
+// Power8
+inline void Assembler::smt_miso() { Assembler::or_unchecked(R26, R26, R26); } // never actually implemented
inline void Assembler::twi_0(Register a) { twi_unchecked(0, a, 0);}
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Tue Apr 10 09:12:23 2018 +0200
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Apr 05 20:09:33 2018 -0400
@@ -2579,7 +2579,6 @@
if (checkRetry) { bind(*checkRetry); }
addic_(retry_count_Reg, retry_count_Reg, -1);
blt(CCR0, doneRetry);
- smt_yield(); // Can't use wait(). No permission (SIGILL).
b(retryLabel);
bind(doneRetry);
}
@@ -2590,7 +2589,7 @@
// output: retry_count_Reg decremented by 1
// CTR is killed
void MacroAssembler::rtm_retry_lock_on_busy(Register retry_count_Reg, Register owner_addr_Reg, Label& retryLabel) {
- Label SpinLoop, doneRetry;
+ Label SpinLoop, doneRetry, doRetry;
addic_(retry_count_Reg, retry_count_Reg, -1);
blt(CCR0, doneRetry);
@@ -2599,16 +2598,26 @@
mtctr(R0);
}
+ // low thread priority
+ smt_prio_low();
bind(SpinLoop);
- smt_yield(); // Can't use waitrsv(). No permission (SIGILL).
if (RTMSpinLoopCount > 1) {
- bdz(retryLabel);
+ bdz(doRetry);
ld(R0, 0, owner_addr_Reg);
cmpdi(CCR0, R0, 0);
bne(CCR0, SpinLoop);
}
+ bind(doRetry);
+
+ // restore thread priority to default in userspace
+#ifdef LINUX
+ smt_prio_medium_low();
+#else
+ smt_prio_medium();
+#endif
+
b(retryLabel);
bind(doneRetry);