#if defined(__sparc__) /* Sparc */
+/*
+ * Solaris has always run sparc processors in TSO (total store) mode, but
+ * linux didn't use to and the *BSDs still don't. So, be careful about
+ * acquire/release semantics. The CPU will treat superflous membars as NOPs,
+ * so it's just code space.
+ */
#define HAS_TEST_AND_SET
typedef unsigned char slock_t;
: "=r"(_res), "+m"(*lock)
: "r"(lock)
: "memory");
+#if defined(__sparcv7)
+ /*
+ * No stbar or membar available, luckily no actually produced hardware
+ * requires a barrier.
+ */
+#elif defined(__sparcv8)
+ /* stbar is available (and required for both PSO, RMO), membar isn't */
+ __asm__ __volatile__ ("stbar \n":::"memory");
+#else
+ /*
+ * #LoadStore (RMO) | #LoadLoad (RMO) together are the appropriate acquire
+ * barrier for sparcv8+ upwards.
+ */
+ __asm__ __volatile__ ("membar #LoadStore | #LoadLoad \n":::"memory");
+#endif
return (int) _res;
}
+#if defined(__sparcv7)
+/*
+ * No stbar or membar available, luckily no actually produced hardware
+ * requires a barrier.
+ */
+#define S_UNLOCK(lock) (*((volatile slock_t *) (lock)) = 0)
+#elif __sparcv8
+/* stbar is available (and required for both PSO, RMO), membar isn't */
+#define S_UNLOCK(lock) \
+do \
+{ \
+ __asm__ __volatile__ ("stbar \n":::"memory"); \
+ *((volatile slock_t *) (lock)) = 0; \
+} while (0)
+#else
+/*
+ * #LoadStore (RMO) | #StoreStore (RMO, PSO) together are the appropriate
+ * release barrier for sparcv8+ upwards.
+ */
+do \
+{ \
+ __asm__ __volatile__ ("membar #LoadStore | #StoreStore \n":::"memory"); \
+ *((volatile slock_t *) (lock)) = 0; \
+} while (0)
+#endif
+
#endif /* __sparc__ */
#endif /* _AIX */
-/* These are in s_lock.c */
+/* These are in sunstudio_(sparc|x86).s */
#if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
#define HAS_TEST_AND_SET