On Fri, Aug 28, 2015 at 09:58:46AM -0400, Tom Lane wrote:
> Noah Misch <n...@leadboat.com> writes:
> > On Thu, Aug 27, 2015 at 10:36:46AM -0400, Tom Lane wrote:
> >> So s_lock.h's PowerPC assembly code works if you have gcc configured to
> >> use gas as backend, but not if it's configured to use the native AIX
> >> assembler.  Steve says the latter configuration is pretty common.
> 
> > These days, the latter configuration is all but universal.  Per the GCC
> > installation instructions, "The GNU Assembler has not been updated to 
> > support
> > AIX 6 or AIX 7."
> 
> Ouch.  I'm surprised we've not gotten more complaints.

That surprised me, too.  Perhaps almost everyone has used either xlc or that
IBM-provided gcc you wrote about.

> >> 2. Don't rely on local symbols in the PPC spinlock assembly code.

> > A third option is to use __sync intrinsics, like we do on ARM.  I like (2).
> 
> I've been waiting to hear confirmation from Steve that the proposed patch
> works with IBM's assembler.  (For all I know, it uses "*" rather than ".",
> or some other randomness.)  He's not responded yet though.  Are you in
> a position to test the patch?

I tested a gcc 64-bit build.  Consistent with your followup, "b .+12" doesn't
build, but "b $+12" builds and passes "make check".  I am attaching the exact
diff I tested.

On GNU/Linux ppc, I get the same opcodes before and after the change.
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index ef66644..b7567c1 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -447,6 +447,12 @@ typedef unsigned int slock_t;
  * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002,
  * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop.
  * On newer machines, we can use lwsync instead for better performance.
+ *
+ * Ordinarily, we'd code the branches here using GNU-style local symbols, that
+ * is "1f" referencing "1:" and so on.  But some people run gcc on AIX with
+ * IBM's assembler as backend, and IBM's assembler doesn't do local symbols.
+ * So hand-code the branch offsets; fortunately, all PPC instructions are
+ * exactly 4 bytes each, so it's not too hard to count.
  */
 static __inline__ int
 tas(volatile slock_t *lock)
@@ -461,20 +467,18 @@ tas(volatile slock_t *lock)
 "      lwarx   %0,0,%3         \n"
 #endif
 "      cmpwi   %0,0            \n"
-"      bne     1f                      \n"
+"      bne     $+16            \n"             /* branch to li %1,1 */
 "      addi    %0,%0,1         \n"
 "      stwcx.  %0,0,%3         \n"
-"      beq     2f              \n"
-"1:    li      %1,1            \n"
-"      b               3f                      \n"
-"2:                                            \n"
+"      beq     $+12            \n"             /* branch to lwsync/isync */
+"      li      %1,1            \n"
+"      b               $+12            \n"             /* branch to end of asm 
sequence */
 #ifdef USE_PPC_LWSYNC
 "      lwsync                          \n"
 #else
 "      isync                           \n"
 #endif
 "      li      %1,0            \n"
-"3:                                            \n"
 
 :      "=&r"(_t), "=r"(_res), "+m"(*lock)
 :      "r"(lock)
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to