mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-13 14:50:17 +00:00
(TSL_SET): backport from db3.
This commit is contained in:
parent
0900b940fb
commit
a92a13f271
@ -1,52 +1,24 @@
|
||||
/*
|
||||
* @(#)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.
|
||||
* @(#)alpha.gcc 11.1 (Sleepycat) 8/30/99
|
||||
*
|
||||
* For gcc/alpha, 0 is clear, 1 is set.
|
||||
*/
|
||||
#define TSL_SET(tsl) ({ \
|
||||
#ifdef __GNUC__
|
||||
#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; \
|
||||
int __r; \
|
||||
asm volatile( \
|
||||
"1: ldl_l %0,%1\n" \
|
||||
" blbs %0,2f\n" \
|
||||
" mov 1,%0\n" \
|
||||
" stl_c %0,%1\n" \
|
||||
" bne %0,1b\n" \
|
||||
" mb\n" \
|
||||
"2:" \
|
||||
: "=&r"(__r), "=m"(*__l) : "m"(*__l) : "memory"); \
|
||||
__r; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#define TSL_UNSET(tsl) ({ \
|
||||
register tsl_t *__l = (tsl); \
|
||||
__asm__ volatile("mb; stq $31,(%0);" : : "r" (__l)); \
|
||||
})
|
||||
#define TSL_UNSET(tsl) (*(tsl) = 0)
|
||||
#define TSL_INIT(tsl) TSL_UNSET(tsl)
|
||||
|
Loading…
Reference in New Issue
Block a user