VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / arch / sparc64 / lib / rwlock.S
1 /* $Id: rwlock.S,v 1.4 2000/09/09 00:00:34 davem Exp $
2  * rwlocks.S: These things are too big to do inline.
3  *
4  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
5  */
6
7         .text
8         .align  64
9
10         /* The non-contention read lock usage is 2 cache lines. */
11
12         .globl  __read_lock, __read_unlock
13 __read_lock: /* %o0 = lock_ptr */
14         ldsw            [%o0], %g5
15         brlz,pn         %g5, __read_wait_for_writer
16 4:       add            %g5, 1, %g7
17         cas             [%o0], %g5, %g7
18         cmp             %g5, %g7
19         bne,pn          %icc, __read_lock
20          membar         #StoreLoad | #StoreStore
21 99:     retl
22          nop
23 __read_unlock: /* %o0 = lock_ptr */
24         lduw            [%o0], %g5
25         sub             %g5, 1, %g7
26         cas             [%o0], %g5, %g7
27         cmp             %g5, %g7
28         be,pt           %xcc, 99b
29          membar         #StoreLoad | #StoreStore
30         ba,a,pt         %xcc, __read_unlock
31
32 __read_wait_for_writer:
33         ldsw            [%o0], %g5
34         brlz,pt         %g5, __read_wait_for_writer
35          membar         #LoadLoad
36         ba,a,pt         %xcc, 4b
37 __write_wait_for_any:
38         lduw            [%o0], %g5
39         brnz,pt         %g5, __write_wait_for_any
40          membar         #LoadLoad
41         ba,a,pt         %xcc, 4f
42
43         .align          64
44         .globl          __write_unlock
45 __write_unlock: /* %o0 = lock_ptr */
46         membar          #LoadStore | #StoreStore
47         retl
48          stw            %g0, [%o0]
49
50         .globl          __write_lock
51 __write_lock: /* %o0 = lock_ptr */
52         sethi           %hi(0x80000000), %g2
53
54 1:      lduw            [%o0], %g5
55         brnz,pn         %g5, __write_wait_for_any
56 4:       or             %g5, %g2, %g7
57         cas             [%o0], %g5, %g7
58
59         cmp             %g5, %g7
60         be,pt           %icc, 99b
61          membar         #StoreLoad | #StoreStore
62         ba,a,pt         %xcc, 1b
63
64         .globl          __write_trylock
65 __write_trylock: /* %o0 = lock_ptr */
66         sethi           %hi(0x80000000), %g2
67 1:      lduw            [%o0], %g5
68         brnz,pn         %g5, __write_trylock_fail
69 4:       or             %g5, %g2, %g7
70
71         cas             [%o0], %g5, %g7
72         cmp             %g5, %g7
73         be,pt           %icc, __write_trylock_succeed
74          membar         #StoreLoad | #StoreStore
75
76         ba,pt           %xcc, 1b
77          nop
78 __write_trylock_succeed:
79         retl
80          mov            1, %o0
81
82 __write_trylock_fail:
83         retl
84          mov            0, %o0
85