import of upstream 2.4.34.4 from kernel.org
[linux-2.4.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         membar          #StoreLoad | #LoadLoad
28         lduw            [%o0], %g5
29         sub             %g5, 1, %g7
30         cas             [%o0], %g5, %g7
31         cmp             %g5, %g7
32         be,pt           %xcc, 99b
33          nop
34         ba,a,pt         %xcc, __read_unlock
35
36 __read_wait_for_writer:
37         ldsw            [%o0], %g5
38         brlz,pt         %g5, __read_wait_for_writer
39          membar         #LoadLoad
40         ba,a,pt         %xcc, 4b
41 __write_wait_for_any:
42         lduw            [%o0], %g5
43         brnz,pt         %g5, __write_wait_for_any
44          membar         #LoadLoad
45         ba,a,pt         %xcc, 4f
46
47         .align          64
48         .globl          __write_unlock
49 __write_unlock: /* %o0 = lock_ptr */
50         membar          #LoadStore | #StoreStore
51         retl
52          stw            %g0, [%o0]
53
54         .globl          __write_lock
55 __write_lock: /* %o0 = lock_ptr */
56         sethi           %hi(0x80000000), %g2
57
58 1:      lduw            [%o0], %g5
59         brnz,pn         %g5, __write_wait_for_any
60 4:       or             %g5, %g2, %g7
61         cas             [%o0], %g5, %g7
62
63         cmp             %g5, %g7
64         be,pt           %icc, 99b
65          membar         #StoreLoad | #StoreStore
66         ba,a,pt         %xcc, 1b
67 rwlock_impl_end:
68