threadpool: Simplify job reference-counting logic.

Use atomic_load_relaxed while here.
This commit is contained in:
riastradh 2020-09-07 01:08:27 +00:00
parent 11002ee06b
commit 340d2bc52e
1 changed files with 11 additions and 22 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_threadpool.c,v 1.18 2020/04/25 17:43:23 thorpej Exp $ */
/* $NetBSD: kern_threadpool.c,v 1.19 2020/09/07 01:08:27 riastradh Exp $ */
/*-
* Copyright (c) 2014, 2018 The NetBSD Foundation, Inc.
@ -81,7 +81,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_threadpool.c,v 1.18 2020/04/25 17:43:23 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_threadpool.c,v 1.19 2020/09/07 01:08:27 riastradh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -762,7 +762,7 @@ threadpool_job_destroy(struct threadpool_job *job)
KASSERTMSG((job->job_thread == NULL), "job %p still running", job);
mutex_enter(job->job_lock);
while (0 < job->job_refcnt)
while (0 < atomic_load_relaxed(&job->job_refcnt))
cv_wait(&job->job_cv, job->job_lock);
mutex_exit(job->job_lock);
@ -778,13 +778,10 @@ threadpool_job_destroy(struct threadpool_job *job)
static void
threadpool_job_hold(struct threadpool_job *job)
{
unsigned int refcnt;
unsigned int refcnt __diagused;
do {
refcnt = job->job_refcnt;
KASSERT(refcnt != UINT_MAX);
} while (atomic_cas_uint(&job->job_refcnt, refcnt, (refcnt + 1))
!= refcnt);
refcnt = atomic_inc_uint_nv(&job->job_refcnt);
KASSERT(refcnt != 0);
}
static void
@ -794,18 +791,10 @@ threadpool_job_rele(struct threadpool_job *job)
KASSERT(mutex_owned(job->job_lock));
do {
refcnt = job->job_refcnt;
KASSERT(0 < refcnt);
if (refcnt == 1) {
refcnt = atomic_dec_uint_nv(&job->job_refcnt);
KASSERT(refcnt != UINT_MAX);
if (refcnt == 0)
cv_broadcast(&job->job_cv);
return;
}
} while (atomic_cas_uint(&job->job_refcnt, refcnt, (refcnt - 1))
!= refcnt);
refcnt = atomic_dec_uint_nv(&job->job_refcnt);
KASSERT(refcnt != UINT_MAX);
if (refcnt == 0)
cv_broadcast(&job->job_cv);
}
void
@ -832,7 +821,7 @@ threadpool_job_done(struct threadpool_job *job)
* threadpool_schedule_job()), and we always do the cv_broadcast()
* anyway.
*/
KASSERT(0 < job->job_refcnt);
KASSERT(0 < atomic_load_relaxed(&job->job_refcnt));
unsigned int refcnt __diagused = atomic_dec_uint_nv(&job->job_refcnt);
KASSERT(refcnt != UINT_MAX);
cv_broadcast(&job->job_cv);