History

locking/rwsem: Introduce rwsem_write_trylock()

One copy of this logic is better than three.

Peter Zijlstra committed 5 years ago

Commit 285c61a1 parent 33791161 file · +16 −22Browse files

Showing the changes to kernel/locking (1 of 1 file). Show all

Unified · Split

kernel/locking/rwsem.c+16−22
@@ -285,6 +285,18 @@ static inline bool rwsem_read_trylock(struct rw_semaphore *sem) · 284 unmodified lines
285 return false;285 return false;
286}286}
287 287
288static inline bool rwsem_write_trylock(struct rw_semaphore *sem)
289{
290 long tmp = RWSEM_UNLOCKED_VALUE;
291
292 if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, RWSEM_WRITER_LOCKED)) {
293 rwsem_set_owner(sem);
294 return true;
295 }
296
297 return false;
298}
299
288/*300/*
289 * Return just the real task structure pointer of the owner301 * Return just the real task structure pointer of the owner
290 */302 */
@@ -1395,42 +1407,24 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) · 1104 unmodified lines
1395 */1407 */
1396static inline void __down_write(struct rw_semaphore *sem)1408static inline void __down_write(struct rw_semaphore *sem)
1397{1409{
1398 long tmp = RWSEM_UNLOCKED_VALUE;1410 if (unlikely(!rwsem_write_trylock(sem)))
1399
1400 if (unlikely(!atomic_long_try_cmpxchg_acquire(&sem->count, &tmp,
1401 RWSEM_WRITER_LOCKED)))
1402 rwsem_down_write_slowpath(sem, TASK_UNINTERRUPTIBLE);1411 rwsem_down_write_slowpath(sem, TASK_UNINTERRUPTIBLE);
1403 else
1404 rwsem_set_owner(sem);
1405}1412}
1406 1413
1407static inline int __down_write_killable(struct rw_semaphore *sem)1414static inline int __down_write_killable(struct rw_semaphore *sem)
1408{1415{
1409 long tmp = RWSEM_UNLOCKED_VALUE;1416 if (unlikely(!rwsem_write_trylock(sem))) {
1410
1411 if (unlikely(!atomic_long_try_cmpxchg_acquire(&sem->count, &tmp,
1412 RWSEM_WRITER_LOCKED))) {
1413 if (IS_ERR(rwsem_down_write_slowpath(sem, TASK_KILLABLE)))1417 if (IS_ERR(rwsem_down_write_slowpath(sem, TASK_KILLABLE)))
1414 return -EINTR;1418 return -EINTR;
1415 } else {
1416 rwsem_set_owner(sem);
1417 }1419 }
1420
1418 return 0;1421 return 0;
1419}1422}
1420 1423
1421static inline int __down_write_trylock(struct rw_semaphore *sem)1424static inline int __down_write_trylock(struct rw_semaphore *sem)
1422{1425{
1423 long tmp;
1424
1425 DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);1426 DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);
1426 1427 return rwsem_write_trylock(sem);
1427 tmp = RWSEM_UNLOCKED_VALUE;
1428 if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp,
1429 RWSEM_WRITER_LOCKED)) {
1430 rwsem_set_owner(sem);
1431 return true;
1432 }
1433 return false;
1434}1428}
1435 1429
1436/*1430/*