about summary refs log tree commit diff
path: root/db2/mutex/sparc.gcc
blob: 5eff1764c8b41b31cee11a2c2d9ad86a26515c6d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
 * @(#)sparc.gcc	10.1 (Sleepycat) 4/12/97
 *
 * The ldstub instruction takes the location specified by its first argument
 * (a register containing a memory address) and loads its contents into its
 * second argument (a register) and atomically sets the contents the location
 * specified by its first argument to a byte of 1s.  (The value in the second
 * argument is never read, but only overwritten.)
 *
 * The membar instructions are needed to ensure that writes to the lock are
 * correctly ordered with writes that occur later in the instruction stream.
 *
 * For gcc/sparc, 0 is clear, 1 is set.
 */

/* The stbar is needed for v8, and is implemented as membar #sync on v9,
   so is functional there as well.  For v7, stbar may generate an illegal
   instruction and we have no way to tell what we're running on.  Some
   operating systems notice and skip this instruction in the fault handler.  */

#define	TSL_SET(tsl) ({							\
	register tsl_t *__l = (tsl);					\
	register tsl_t __r;						\
	__asm__ volatile						\
	    ("ldstub [%1],%0; stbar"					\
	    : "=r"( __r) : "r" (__l));					\
	!__r;								\
})

#define	TSL_UNSET(tsl)	(*(tsl) = 0)
#define	TSL_INIT(tsl)	TSL_UNSET(tsl)