diff options
| -rw-r--r-- | include/linux/spinlock.h | 5 | ||||
| -rw-r--r-- | lib/dec_and_lock.c | 16 |
2 files changed, 21 insertions, 0 deletions
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 1e8a46435838..fd57888d4942 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h | |||
| @@ -427,6 +427,11 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); | |||
| 427 | #define atomic_dec_and_lock(atomic, lock) \ | 427 | #define atomic_dec_and_lock(atomic, lock) \ |
| 428 | __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) | 428 | __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) |
| 429 | 429 | ||
| 430 | extern int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock, | ||
| 431 | unsigned long *flags); | ||
| 432 | #define atomic_dec_and_lock_irqsave(atomic, lock, flags) \ | ||
| 433 | __cond_lock(lock, _atomic_dec_and_lock_irqsave(atomic, lock, &(flags))) | ||
| 434 | |||
| 430 | int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, | 435 | int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, |
| 431 | size_t max_size, unsigned int cpu_mult, | 436 | size_t max_size, unsigned int cpu_mult, |
| 432 | gfp_t gfp); | 437 | gfp_t gfp); |
diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c index 347fa7ac2e8a..9555b68bb774 100644 --- a/lib/dec_and_lock.c +++ b/lib/dec_and_lock.c | |||
| @@ -33,3 +33,19 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) | |||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | EXPORT_SYMBOL(_atomic_dec_and_lock); | 35 | EXPORT_SYMBOL(_atomic_dec_and_lock); |
| 36 | |||
| 37 | int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock, | ||
| 38 | unsigned long *flags) | ||
| 39 | { | ||
| 40 | /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ | ||
| 41 | if (atomic_add_unless(atomic, -1, 1)) | ||
| 42 | return 0; | ||
| 43 | |||
| 44 | /* Otherwise do it the slow way */ | ||
| 45 | spin_lock_irqsave(lock, *flags); | ||
| 46 | if (atomic_dec_and_test(atomic)) | ||
| 47 | return 1; | ||
| 48 | spin_unlock_irqrestore(lock, *flags); | ||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | EXPORT_SYMBOL(_atomic_dec_and_lock_irqsave); | ||
