summaryrefslogtreecommitdiffstats
path: root/src/backend/port/hpux/tas.c.template
blob: 5ccbbcde9aa415b02188270032253d63c2f7a19a (plain)
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
32
33
34
35
36
37
38
39
40
/*
 * tas() for HPPA.
 *
 * To generate tas.s using this template:
 *	1. cc +O2 -S -c tas.c
 *	2. edit tas.s:
 *		- replace the LDW with LDCWX
 *	3. install as src/backend/port/tas/hpux_hppa.s.
 *
 * For details about the LDCWX instruction, see the "Precision
 * Architecture and Instruction Reference Manual" (09740-90014 of June
 * 1987), p. 5-38.
 */

int
tas(lock)
    int *lock;	/* LDCWX is a word instruction */
{
    /*
     * LDCWX requires that we align the "semaphore" to a 16-byte
     * boundary.  The actual datum is a single word (4 bytes).
     */
    lock = ((uintptr_t) lock + 15) & ~15;

    /*
     * The LDCWX instruction atomically clears the target word and
     * returns the previous value.  Hence, if the instruction returns
     * 0, someone else has already acquired the lock before we tested
     * it (i.e., we have failed).
     *
     * Notice that this means that we actually clear the word to set
     * the lock and set the word to clear the lock.  This is the
     * opposite behavior from the SPARC LDSTUB instruction.  For some
     * reason everything that H-P does is rather baroque...
     */
    if (*lock) {	/* this generates the LDW */
	return(0);	/* success */
    }
    return(1);    	/* failure */
}