Back-patch fix for correct TAS operation on multi-CPU PPC machines.
authorTom Lane <[email protected]>
Mon, 30 Sep 2002 20:24:53 +0000 (20:24 +0000)
committerTom Lane <[email protected]>
Mon, 30 Sep 2002 20:24:53 +0000 (20:24 +0000)
src/backend/storage/lmgr/s_lock.c
src/include/storage/s_lock.h

index 4d951e79abefdc630fb09f033e802b34b7037760..3551abaae562d09d2bd6a2daecae6fc8e294c6e6 100644 (file)
@@ -115,6 +115,9 @@ _success:                                           \n\
 /* used in darwin. */
 /* We key off __APPLE__ here because this function differs from
  * the LinuxPPC implementation only in compiler syntax.
+ *
+ * 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.
  */
 static void
 tas_dummy()
@@ -134,6 +137,7 @@ tas:                                                        \n\
 fail:          li              r3,1            \n\
                        blr                             \n\
 success:                                               \n\
+                       isync                           \n\
                        li              r3,0            \n\
                        blr                                     \n\
 ");
@@ -158,6 +162,7 @@ tas:                                                        \n\
 fail:          li              3,1             \n\
                        blr                             \n\
 success:                                               \n\
+                       isync                           \n\
                        li              3,0                     \n\
                        blr                                     \n\
 ");
index 711b7ee5854c28a206d01cafdf87f44e7bd722e1..1e01fe86fe04fa54dc36c70022fc8839fdec2909 100644 (file)
@@ -217,6 +217,21 @@ tas(volatile slock_t *lock)
 #endif  /* defined(__mc68000__) && defined(__linux__) */
 
 
+#if defined(__ppc__) || defined(__powerpc__)
+/*
+ * We currently use out-of-line assembler for TAS on PowerPC; see s_lock.c.
+ * S_UNLOCK is almost standard but requires a "sync" instruction.
+ */
+#define S_UNLOCK(lock) \
+do \
+{\
+       __asm__ __volatile__ (" sync \n"); \
+       *((volatile slock_t *) (lock)) = 0; \
+} while (0)
+
+#endif /* defined(__ppc__) || defined(__powerpc__) */
+
+
 #if defined(NEED_VAX_TAS_ASM)
 /*
  * VAXen -- even multiprocessor ones