Provide an API for interlocked refcount sleeps.
Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D22908
This commit is contained in:
parent
28479aaae2
commit
811d05fcb7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356885
@ -381,15 +381,21 @@ refcount_release_last(volatile u_int *count, u_int n, u_int old)
|
||||
* a precise answer should use refcount_wait().
|
||||
*/
|
||||
void
|
||||
refcount_sleep(volatile u_int *count, const char *wmesg, int pri)
|
||||
_refcount_sleep(volatile u_int *count, struct lock_object *lock,
|
||||
const char *wmesg, int pri)
|
||||
{
|
||||
void *wchan;
|
||||
u_int old;
|
||||
|
||||
if (REFCOUNT_COUNT(*count) == 0)
|
||||
if (REFCOUNT_COUNT(*count) == 0) {
|
||||
if (lock != NULL)
|
||||
LOCK_CLASS(lock)->lc_unlock(lock);
|
||||
return;
|
||||
}
|
||||
wchan = __DEVOLATILE(void *, count);
|
||||
sleepq_lock(wchan);
|
||||
if (lock != NULL)
|
||||
LOCK_CLASS(lock)->lc_unlock(lock);
|
||||
old = *count;
|
||||
for (;;) {
|
||||
if (REFCOUNT_COUNT(old) == 0) {
|
||||
|
@ -46,7 +46,6 @@
|
||||
#define REFCOUNT_COUNT(x) ((x) & ~REFCOUNT_WAITER)
|
||||
|
||||
bool refcount_release_last(volatile u_int *count, u_int n, u_int old);
|
||||
void refcount_sleep(volatile u_int *count, const char *wmesg, int prio);
|
||||
|
||||
/*
|
||||
* Attempt to handle reference count overflow and underflow. Force the counter
|
||||
@ -135,6 +134,21 @@ refcount_release(volatile u_int *count)
|
||||
return (refcount_releasen(count, 1));
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct lock_object;
|
||||
void _refcount_sleep(volatile u_int *count, struct lock_object *,
|
||||
const char *wmesg, int prio);
|
||||
|
||||
static __inline void
|
||||
refcount_sleep(volatile u_int *count, const char *wmesg, int prio)
|
||||
{
|
||||
|
||||
_refcount_sleep(count, NULL, wmesg, prio);
|
||||
}
|
||||
|
||||
#define refcount_sleep_interlock(count, lock, wmesg, prio) \
|
||||
_refcount_sleep((count), (struct lock_object *)(lock), (wmesg), (prio))
|
||||
|
||||
static __inline void
|
||||
refcount_wait(volatile u_int *count, const char *wmesg, int prio)
|
||||
{
|
||||
@ -142,6 +156,7 @@ refcount_wait(volatile u_int *count, const char *wmesg, int prio)
|
||||
while (*count != 0)
|
||||
refcount_sleep(count, wmesg, prio);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This functions returns non-zero if the refcount was
|
||||
|
Loading…
Reference in New Issue
Block a user