ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[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         .globl  rwlock_impl_begin, rwlock_impl_end
11
12         /* The non-contention read lock usage is 2 cache lines. */
13
14         .globl  __read_lock, __read_unlock
15 rwlock_impl_begin:
16 __read_lock: /* %o0 = lock_ptr */
17         ldsw            [%o0], %g5
18         brlz,pn         %g5, __read_wait_for_writer
19 4:       add            %g5, 1, %g7
20         cas             [%o0], %g5, %g7
21         cmp             %g5, %g7
22         bne,pn          %icc, __read_lock
23          membar         #StoreLoad | #StoreStore
24 99:     retl
25          nop
26 __read_unlock: /* %o0 = lock_ptr */
27         lduw            [%o0], %g5
28         sub             %g5, 1, %g7
29         cas             [%o0], %g5, %g7
30         cmp             %g5, %g7
31         be,pt           %xcc, 99b
32          membar         #StoreLoad | #StoreStore
33         ba,a,pt         %xcc, __read_unlock
34
35 __read_wait_for_writer:
36         ldsw            [%o0], %g5
37         brlz,pt         %g5, __read_wait_for_writer
38          membar         #LoadLoad
39         ba,a,pt         %xcc, 4b
40 __write_wait_for_any:
41         lduw            [%o0], %g5
42         brnz,pt         %g5, __write_wait_for_any
43          membar         #LoadLoad
44         ba,a,pt         %xcc, 4f
45
46         .align          64
47         .globl          __write_unlock
48 __write_unlock: /* %o0 = lock_ptr */
49         membar          #LoadStore | #StoreStore
50         retl
51          stw            %g0, [%o0]
52
53         .globl          __write_lock
54 __write_lock: /* %o0 = lock_ptr */
55         sethi           %hi(0x80000000), %g2
56
57 1:      lduw            [%o0], %g5
58         brnz,pn         %g5, __write_wait_for_any
59 4:       or             %g5, %g2, %g7
60         cas             [%o0], %g5, %g7
61
62         cmp             %g5, %g7
63         be,pt           %icc, 99b
64          membar         #StoreLoad | #StoreStore
65         ba,a,pt         %xcc, 1b
66
67         .globl          __write_trylock
68 __write_trylock: /* %o0 = lock_ptr */
69         sethi           %hi(0x80000000), %g2
70 1:      lduw            [%o0], %g5
71         brnz,pn         %g5, __write_trylock_fail
72 4:       or             %g5, %g2, %g7
73
74         cas             [%o0], %g5, %g7
75         cmp             %g5, %g7
76         be,pt           %icc, __write_trylock_succeed
77          membar         #StoreLoad | #StoreStore
78
79         ba,pt           %xcc, 1b
80          nop
81 __write_trylock_succeed:
82         retl
83          mov            1, %o0
84
85 __write_trylock_fail:
86         retl
87          mov            0, %o0
88 rwlock_impl_end:
89