diff options
Diffstat (limited to 'arch/tile/include/asm/spinlock_32.h')
-rw-r--r-- | arch/tile/include/asm/spinlock_32.h | 83 |
1 files changed, 7 insertions, 76 deletions
diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h index 88efdde8dd2..a8f2c6e31a8 100644 --- a/arch/tile/include/asm/spinlock_32.h +++ b/arch/tile/include/asm/spinlock_32.h | |||
@@ -78,13 +78,6 @@ void arch_spin_unlock_wait(arch_spinlock_t *lock); | |||
78 | #define _RD_COUNT_SHIFT 24 | 78 | #define _RD_COUNT_SHIFT 24 |
79 | #define _RD_COUNT_WIDTH 8 | 79 | #define _RD_COUNT_WIDTH 8 |
80 | 80 | ||
81 | /* Internal functions; do not use. */ | ||
82 | void arch_read_lock_slow(arch_rwlock_t *, u32); | ||
83 | int arch_read_trylock_slow(arch_rwlock_t *); | ||
84 | void arch_read_unlock_slow(arch_rwlock_t *); | ||
85 | void arch_write_lock_slow(arch_rwlock_t *, u32); | ||
86 | void arch_write_unlock_slow(arch_rwlock_t *, u32); | ||
87 | |||
88 | /** | 81 | /** |
89 | * arch_read_can_lock() - would read_trylock() succeed? | 82 | * arch_read_can_lock() - would read_trylock() succeed? |
90 | */ | 83 | */ |
@@ -104,94 +97,32 @@ static inline int arch_write_can_lock(arch_rwlock_t *rwlock) | |||
104 | /** | 97 | /** |
105 | * arch_read_lock() - acquire a read lock. | 98 | * arch_read_lock() - acquire a read lock. |
106 | */ | 99 | */ |
107 | static inline void arch_read_lock(arch_rwlock_t *rwlock) | 100 | void arch_read_lock(arch_rwlock_t *rwlock); |
108 | { | ||
109 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
110 | if (unlikely(val << _RD_COUNT_WIDTH)) { | ||
111 | arch_read_lock_slow(rwlock, val); | ||
112 | return; | ||
113 | } | ||
114 | rwlock->lock = val + (1 << _RD_COUNT_SHIFT); | ||
115 | } | ||
116 | 101 | ||
117 | /** | 102 | /** |
118 | * arch_read_lock() - acquire a write lock. | 103 | * arch_write_lock() - acquire a write lock. |
119 | */ | 104 | */ |
120 | static inline void arch_write_lock(arch_rwlock_t *rwlock) | 105 | void arch_write_lock(arch_rwlock_t *rwlock); |
121 | { | ||
122 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
123 | if (unlikely(val != 0)) { | ||
124 | arch_write_lock_slow(rwlock, val); | ||
125 | return; | ||
126 | } | ||
127 | rwlock->lock = 1 << _WR_NEXT_SHIFT; | ||
128 | } | ||
129 | 106 | ||
130 | /** | 107 | /** |
131 | * arch_read_trylock() - try to acquire a read lock. | 108 | * arch_read_trylock() - try to acquire a read lock. |
132 | */ | 109 | */ |
133 | static inline int arch_read_trylock(arch_rwlock_t *rwlock) | 110 | int arch_read_trylock(arch_rwlock_t *rwlock); |
134 | { | ||
135 | int locked; | ||
136 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
137 | if (unlikely(val & 1)) | ||
138 | return arch_read_trylock_slow(rwlock); | ||
139 | locked = (val << _RD_COUNT_WIDTH) == 0; | ||
140 | rwlock->lock = val + (locked << _RD_COUNT_SHIFT); | ||
141 | return locked; | ||
142 | } | ||
143 | 111 | ||
144 | /** | 112 | /** |
145 | * arch_write_trylock() - try to acquire a write lock. | 113 | * arch_write_trylock() - try to acquire a write lock. |
146 | */ | 114 | */ |
147 | static inline int arch_write_trylock(arch_rwlock_t *rwlock) | 115 | int arch_write_trylock(arch_rwlock_t *rwlock); |
148 | { | ||
149 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
150 | |||
151 | /* | ||
152 | * If a tns is in progress, or there's a waiting or active locker, | ||
153 | * or active readers, we can't take the lock, so give up. | ||
154 | */ | ||
155 | if (unlikely(val != 0)) { | ||
156 | if (!(val & 1)) | ||
157 | rwlock->lock = val; | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* Set the "next" field to mark it locked. */ | ||
162 | rwlock->lock = 1 << _WR_NEXT_SHIFT; | ||
163 | return 1; | ||
164 | } | ||
165 | 116 | ||
166 | /** | 117 | /** |
167 | * arch_read_unlock() - release a read lock. | 118 | * arch_read_unlock() - release a read lock. |
168 | */ | 119 | */ |
169 | static inline void arch_read_unlock(arch_rwlock_t *rwlock) | 120 | void arch_read_unlock(arch_rwlock_t *rwlock); |
170 | { | ||
171 | u32 val; | ||
172 | mb(); /* guarantee anything modified under the lock is visible */ | ||
173 | val = __insn_tns((int *)&rwlock->lock); | ||
174 | if (unlikely(val & 1)) { | ||
175 | arch_read_unlock_slow(rwlock); | ||
176 | return; | ||
177 | } | ||
178 | rwlock->lock = val - (1 << _RD_COUNT_SHIFT); | ||
179 | } | ||
180 | 121 | ||
181 | /** | 122 | /** |
182 | * arch_write_unlock() - release a write lock. | 123 | * arch_write_unlock() - release a write lock. |
183 | */ | 124 | */ |
184 | static inline void arch_write_unlock(arch_rwlock_t *rwlock) | 125 | void arch_write_unlock(arch_rwlock_t *rwlock); |
185 | { | ||
186 | u32 val; | ||
187 | mb(); /* guarantee anything modified under the lock is visible */ | ||
188 | val = __insn_tns((int *)&rwlock->lock); | ||
189 | if (unlikely(val != (1 << _WR_NEXT_SHIFT))) { | ||
190 | arch_write_unlock_slow(rwlock, val); | ||
191 | return; | ||
192 | } | ||
193 | rwlock->lock = 0; | ||
194 | } | ||
195 | 126 | ||
196 | #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) | 127 | #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) |
197 | #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) | 128 | #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) |