diff options
Diffstat (limited to 'db2/mutex/alpha.gcc')
-rw-r--r-- | db2/mutex/alpha.gcc | 52 |
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) |