summaryrefslogtreecommitdiff
path: root/db2/mutex/alpha.gcc
diff options
context:
space:
mode:
Diffstat (limited to 'db2/mutex/alpha.gcc')
-rw-r--r--db2/mutex/alpha.gcc52
1 files changed, 52 insertions, 0 deletions
diff --git a/db2/mutex/alpha.gcc b/db2/mutex/alpha.gcc
new file mode 100644
index 0000000000..247d04cf31
--- /dev/null
+++ b/db2/mutex/alpha.gcc
@@ -0,0 +1,52 @@
+/*
+ * @(#)alpha.gcc 10.1 (Sleepycat) 4/12/97
+ *
+ * The code appearing below is taken from Richard L. Sites, ed. "Alpha
+ * Architecture Reference Manual", Digital Press, 1992, page 5-7 and 5-8.
+ * There are 2 modifications:
+ *
+ * 1. The jump from blbs __r1,30f to !__r1, which is dictated by the way the
+ * TSL_SET macro is used. The code suggested in Sites includes the main loop
+ * of the spin lock, whereas in this code the rest the loop is specified in C.
+ * The generated code might be suboptimal if the compiler generates a forward
+ * branch for the usual case in which the mutex is uncontested.
+ *
+ * 2. At label 20, Sites suggests including code for testing for an excessive
+ * number of _processor_ lock conflicts. (The seq_c instruction stores its
+ * first argument provided that no other processor has written to a byte range
+ * including its memory-location argument.) Absent such checking the code
+ * below could conceivably stall silently on a multiprocessor alpha, depending
+ * on how often processor/processor conflicts occur in a particular byte range.
+ *
+ * Note that the mb ("memory-barrier") instruction in TSL_UNSET is critical to
+ * correct operation in a multiprocessor alpha (as is, of course, the mb in
+ * the TSL_SET macro). Without the mb, changes to shared memory that occurred
+ * inside the critical section (before the TSL_UNSET) might reach shared memory
+ * _after_ the change of tsl to 0, thereby permitting another processor to see
+ * an inconsistent view of the data protected by the mutex.
+ *
+ * For gcc/alpha, 0 is clear, 1 is set.
+ */
+#define TSL_SET(tsl) ({ \
+ register tsl_t *__l = (tsl); \
+ register tsl_t __r1, __r2; \
+ __asm__ volatile(" \n\
+ 10: ldq_l %0,(%2) \n\
+ blbs %0,30f \n\
+ or %0,1,%1 \n\
+ stq_c %1,(%2) \n\
+ beq %1,20f \n\
+ mb \n\
+ br 30f \n\
+ 20: br 10b \n\
+ 30: " \
+ : "=&r" (__r1), "=&r" (__r2) \
+ : "r" (__l)); \
+ !__r1; \
+})
+
+#define TSL_UNSET(tsl) ({ \
+ register tsl_t *__l = (tsl); \
+ __asm__ volatile("mb; stq $31,(%0);" : : "r" (__l)); \
+})
+#define TSL_INIT(tsl) TSL_UNSET(tsl)