Details
Description
The following patch is suggested by Stewart Smith:
On POWER, you can set thread priority rather than Intel relax cpu instruction
So the correct way to write a spin loop for POWER is to lower the thread
priority while you spin and raise it up afterwards.
We add the asm volatile("":::"memory"); bit of asm to make GCC not optimize
the spin loop down to a nop. This is a GCC barrier rather than a CPU memory
barrier - and is arguably needed for x86 as well
Index: mysql-5.6.17/storage/innobase/sync/sync0rw.cc
===================================================================
--- mysql-5.6.17.orig/storage/innobase/sync/sync0rw.cc 2014-05-26 12:16:25.622071001 +1000
+++ mysql-5.6.17/storage/innobase/sync/sync0rw.cc 2014-05-26 17:37:14.702071000 +1000
@@ -382,6 +382,7 @@
/* Spin waiting for the writer field to become free */
os_rmb;
+ asm volatile ("or 1,1,1");
while (i < SYNC_SPIN_ROUNDS && lock->lock_word <= 0) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
@@ -393,7 +394,9 @@
#else
i++;
#endif /* HAVE_MEMORY_BARRIER */
+ asm volatile ("":::"memory");
}
+ asm volatile ("or 2,2,2");
if (i >= SYNC_SPIN_ROUNDS) {
os_thread_yield();
Index: mysql-5.6.17/storage/innobase/sync/sync0sync.cc
===================================================================
--- mysql-5.6.17.orig/storage/innobase/sync/sync0sync.cc 2014-05-26 12:16:25.622071001 +1000
+++ mysql-5.6.17/storage/innobase/sync/sync0sync.cc 2014-05-26 17:37:52.152071000 +1000
@@ -501,6 +501,7 @@
spin_loop:
os_rmb;
+ asm volatile("or 1,1,1");
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
@@ -512,7 +513,9 @@
#else
i++;
#endif /* HAVE_MEMORY_BARRIER */
+ asm volatile("":::"memory");
}
+ asm volatile ("or 2,2,2;");
if (i >= SYNC_SPIN_ROUNDS) {
os_thread_yield();
Gliffy Diagrams
Attachments
Issue Links
- is part of
-
MDEV-6530 Examine and apply Power8 patches suggested by Stewart Smith
-
- Open
-
- links to
Activity
- All
- Comments
- Work Log
- History
- Activity
- Transitions
I would argue that this patch is not needed.
Reason:
The loop in /storage/innobase/sync/sync0sync.cc will never be optimized away by gcc because of the code we have in mutex_get_lock_word(mutex), which is part of the loop:
This should make the original code safe.
The other loop also references a volatile argument, so this is also safe.
I suggest we don't take this patch (unless someone can show us an assembler output where the loop is optimized away).