|
@@ -151,4 +151,27 @@ extern int __must_check mutex_lock_killable(struct mutex *lock);
|
|
extern int mutex_trylock(struct mutex *lock);
|
|
extern int mutex_trylock(struct mutex *lock);
|
|
extern void mutex_unlock(struct mutex *lock);
|
|
extern void mutex_unlock(struct mutex *lock);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0
|
|
|
|
+ * @cnt: the atomic which we are to dec
|
|
|
|
+ * @lock: the mutex to return holding if we dec to 0
|
|
|
|
+ *
|
|
|
|
+ * return true and hold lock if we dec to 0, return false otherwise
|
|
|
|
+ */
|
|
|
|
+static inline int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock)
|
|
|
|
+{
|
|
|
|
+ /* dec if we can't possibly hit 0 */
|
|
|
|
+ if (atomic_add_unless(cnt, -1, 1))
|
|
|
|
+ return 0;
|
|
|
|
+ /* we might hit 0, so take the lock */
|
|
|
|
+ mutex_lock(lock);
|
|
|
|
+ if (!atomic_dec_and_test(cnt)) {
|
|
|
|
+ /* when we actually did the dec, we didn't hit 0 */
|
|
|
|
+ mutex_unlock(lock);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ /* we hit 0, and we hold the lock */
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
#endif
|
|
#endif
|