diff options
Diffstat (limited to 'lib/dec_and_lock.c')
| -rw-r--r-- | lib/dec_and_lock.c | 31 | 
1 files changed, 31 insertions, 0 deletions
diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c index 9555b68bb774..1dcca8f2e194 100644 --- a/lib/dec_and_lock.c +++ b/lib/dec_and_lock.c @@ -49,3 +49,34 @@ int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock,  	return 0;  }  EXPORT_SYMBOL(_atomic_dec_and_lock_irqsave); + +int _atomic_dec_and_raw_lock(atomic_t *atomic, raw_spinlock_t *lock) +{ +	/* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ +	if (atomic_add_unless(atomic, -1, 1)) +		return 0; + +	/* Otherwise do it the slow way */ +	raw_spin_lock(lock); +	if (atomic_dec_and_test(atomic)) +		return 1; +	raw_spin_unlock(lock); +	return 0; +} +EXPORT_SYMBOL(_atomic_dec_and_raw_lock); + +int _atomic_dec_and_raw_lock_irqsave(atomic_t *atomic, raw_spinlock_t *lock, +				     unsigned long *flags) +{ +	/* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ +	if (atomic_add_unless(atomic, -1, 1)) +		return 0; + +	/* Otherwise do it the slow way */ +	raw_spin_lock_irqsave(lock, *flags); +	if (atomic_dec_and_test(atomic)) +		return 1; +	raw_spin_unlock_irqrestore(lock, *flags); +	return 0; +} +EXPORT_SYMBOL(_atomic_dec_and_raw_lock_irqsave);  | 
