One copy of this logic is better than three.
Showing the changes to kernel/locking (1 of 1 file). Show all
Unified · Split
| @@ -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 | ||
| 288 | static 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 owner | 301 | * 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 | */ |
| 1396 | static inline void __down_write(struct rw_semaphore *sem) | 1408 | static 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 | ||
| 1407 | static inline int __down_write_killable(struct rw_semaphore *sem) | 1414 | static 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 | ||
| 1421 | static inline int __down_write_trylock(struct rw_semaphore *sem) | 1424 | static 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 | /* |