1
2
3
4
5
6
7
8
9#ifndef _ASM_SPINLOCK_H
10#define _ASM_SPINLOCK_H
11
12
13
14
15
16typedef struct {
17 volatile unsigned int lock;
18} spinlock_t;
19
20#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
21
22#define spin_lock_init(x) do { (x)->lock = 0; } while(0)
23
24#define spin_is_locked(x) ((x)->lock != 0)
25#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock)
26
27
28
29
30
31
32
33
34static inline void spin_lock(spinlock_t *lock)
35{
36 unsigned int tmp;
37
38 __asm__ __volatile__(
39 ".set\tnoreorder\t\t\t# spin_lock\n"
40 "1:\tll\t%1, %2\n\t"
41 "bnez\t%1, 1b\n\t"
42 " li\t%1, 1\n\t"
43 "sc\t%1, %0\n\t"
44 "beqz\t%1, 1b\n\t"
45 " sync\n\t"
46 ".set\treorder"
47 : "=m" (lock->lock), "=&r" (tmp)
48 : "m" (lock->lock)
49 : "memory");
50}
51
52static inline void spin_unlock(spinlock_t *lock)
53{
54 __asm__ __volatile__(
55 ".set\tnoreorder\t\t\t# spin_unlock\n\t"
56 "sync\n\t"
57 "sw\t$0, %0\n\t"
58 ".set\treorder"
59 : "=m" (lock->lock)
60 : "m" (lock->lock)
61 : "memory");
62}
63
64static inline unsigned int spin_trylock(spinlock_t *lock)
65{
66 unsigned int temp, res;
67
68 __asm__ __volatile__(
69 ".set\tnoreorder\t\t\t# spin_trylock\n\t"
70 "1:\tll\t%0, %1\n\t"
71 "or\t%2, %0, %3\n\t"
72 "sc\t%2, %1\n\t"
73 "beqz\t%2, 1b\n\t"
74 " and\t%2, %0, %3\n\t"
75 ".set\treorder"
76 : "=&r" (temp), "=m" (lock->lock), "=&r" (res)
77 : "r" (1), "m" (lock->lock)
78 : "memory");
79
80 return res == 0;
81}
82
83
84
85
86
87
88
89
90
91
92typedef struct {
93 volatile unsigned int lock;
94} rwlock_t;
95
96#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
97
98#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
99
100static inline void read_lock(rwlock_t *rw)
101{
102 unsigned int tmp;
103
104 __asm__ __volatile__(
105 ".set\tnoreorder\t\t\t# read_lock\n"
106 "1:\tll\t%1, %2\n\t"
107 "bltz\t%1, 1b\n\t"
108 " addu\t%1, 1\n\t"
109 "sc\t%1, %0\n\t"
110 "beqz\t%1, 1b\n\t"
111 " sync\n\t"
112 ".set\treorder"
113 : "=m" (rw->lock), "=&r" (tmp)
114 : "m" (rw->lock)
115 : "memory");
116}
117
118
119
120
121static inline void read_unlock(rwlock_t *rw)
122{
123 unsigned int tmp;
124
125 __asm__ __volatile__(
126 ".set\tnoreorder\t\t\t# read_unlock\n"
127 "1:\tll\t%1, %2\n\t"
128 "sub\t%1, 1\n\t"
129 "sc\t%1, %0\n\t"
130 "beqz\t%1, 1b\n\t"
131 " sync\n\t"
132 ".set\treorder"
133 : "=m" (rw->lock), "=&r" (tmp)
134 : "m" (rw->lock)
135 : "memory");
136}
137
138static inline void write_lock(rwlock_t *rw)
139{
140 unsigned int tmp;
141
142 __asm__ __volatile__(
143 ".set\tnoreorder\t\t\t# write_lock\n"
144 "1:\tll\t%1, %2\n\t"
145 "bnez\t%1, 1b\n\t"
146 " lui\t%1, 0x8000\n\t"
147 "sc\t%1, %0\n\t"
148 "beqz\t%1, 1b\n\t"
149 " sync\n\t"
150 ".set\treorder"
151 : "=m" (rw->lock), "=&r" (tmp)
152 : "m" (rw->lock)
153 : "memory");
154}
155
156static inline void write_unlock(rwlock_t *rw)
157{
158 __asm__ __volatile__(
159 ".set\tnoreorder\t\t\t# write_unlock\n\t"
160 "sync\n\t"
161 "sw\t$0, %0\n\t"
162 ".set\treorder"
163 : "=m" (rw->lock)
164 : "m" (rw->lock)
165 : "memory");
166}
167
168#endif
169