1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include "two_state_shared_lock.h"
4 
5 void bch2_two_state_unlock(two_state_lock_t *lock, int s)
6 {
7 	long i = s ? 1 : -1;
8 
9 	BUG_ON(atomic_long_read(&lock->v) == 0);
10 
11 	if (atomic_long_sub_return_release(i, &lock->v) == 0)
12 		wake_up_all(&lock->wait);
13 }
14 
15 bool bch2_two_state_trylock(two_state_lock_t *lock, int s)
16 {
17 	long i = s ? 1 : -1;
18 	long v = atomic_long_read(&lock->v), old;
19 
20 	do {
21 		old = v;
22 
23 		if (i > 0 ? v < 0 : v > 0)
24 			return false;
25 	} while ((v = atomic_long_cmpxchg_acquire(&lock->v,
26 					old, old + i)) != old);
27 	return true;
28 }
29 
30 void bch2_two_state_lock(two_state_lock_t *lock, int s)
31 {
32 	wait_event(lock->wait, bch2_two_state_trylock(lock, s));
33 }
34