From 340d2bc52e9ac4899e4a668fd2cfaefd6ebc6feb Mon Sep 17 00:00:00 2001 From: riastradh Date: Mon, 7 Sep 2020 01:08:27 +0000 Subject: [PATCH] threadpool: Simplify job reference-counting logic. Use atomic_load_relaxed while here. --- sys/kern/kern_threadpool.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/sys/kern/kern_threadpool.c b/sys/kern/kern_threadpool.c index 09a8bc22d622..42b7c2f2e324 100644 --- a/sys/kern/kern_threadpool.c +++ b/sys/kern/kern_threadpool.c @@ -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 -__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 #include @@ -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);