Module Name:    src
Committed By:   riastradh
Date:           Wed Jan 13 02:20:15 UTC 2021

Modified Files:
        src/sys/kern: kern_threadpool.c

Log Message:
threadpool(9): Tidy up thread naming.

- `dispatcher', not `overseer' -- much more appropriate metaphor.
- Just omit `/-1' from unbound thread names.
- Just omit `@-1' from dynamic-priority (PRI_NONE) thread names.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/sys/kern/kern_threadpool.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_threadpool.c
diff -u src/sys/kern/kern_threadpool.c:1.20 src/sys/kern/kern_threadpool.c:1.21
--- src/sys/kern/kern_threadpool.c:1.20	Wed Jan 13 02:19:08 2021
+++ src/sys/kern/kern_threadpool.c	Wed Jan 13 02:20:15 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_threadpool.c,v 1.20 2021/01/13 02:19:08 riastradh Exp $	*/
+/*	$NetBSD: kern_threadpool.c,v 1.21 2021/01/13 02:20:15 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2014, 2018 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
  * Thread pools.
  *
  * A thread pool is a collection of worker threads idle or running
- * jobs, together with an overseer thread that does not run jobs but
+ * jobs, together with an dispatcher thread that does not run jobs but
  * can be given jobs to assign to a worker thread.  Scheduling a job in
  * a thread pool does not allocate or even sleep at all, except perhaps
  * on an adaptive lock, unlike kthread_create.  Jobs reuse threads, so
@@ -56,32 +56,32 @@
  * CPU.  When you're done, call threadpool_percpu_put(pool_percpu,
  * pri).
  *
- * +--MACHINE-----------------------------------------------+
- * | +--CPU 0-------+ +--CPU 1-------+     +--CPU n-------+ |
- * | | <overseer 0> | | <overseer 1> | ... | <overseer n> | |
- * | | <idle 0a>    | | <running 1a> | ... | <idle na>    | |
- * | | <running 0b> | | <running 1b> | ... | <idle nb>    | |
- * | | .            | | .            | ... | .            | |
- * | | .            | | .            | ... | .            | |
- * | | .            | | .            | ... | .            | |
- * | +--------------+ +--------------+     +--------------+ |
- * |            +--unbound---------+                        |
- * |            | <overseer n+1>   |                        |
- * |            | <idle (n+1)a>    |                        |
- * |            | <running (n+1)b> |                        |
- * |            +------------------+                        |
- * +--------------------------------------------------------+
+ * +--MACHINE-----------------------------------------------------+
+ * | +--CPU 0---------+ +--CPU 1---------+     +--CPU n---------+ |
+ * | | <dispatcher 0> | | <dispatcher 1> | ... | <dispatcher n> | |
+ * | | <idle 0a>      | | <running 1a>   | ... | <idle na>      | |
+ * | | <running 0b>   | | <running 1b>   | ... | <idle nb>      | |
+ * | | .              | | .              | ... | .              | |
+ * | | .              | | .              | ... | .              | |
+ * | | .              | | .              | ... | .              | |
+ * | +----------------+ +----------------+     +----------------+ |
+ * |            +--unbound-----------+                            |
+ * |            | <dispatcher n+1>   |                            |
+ * |            | <idle (n+1)a>      |                            |
+ * |            | <running (n+1)b>   |                            |
+ * |            +--------------------+                            |
+ * +--------------------------------------------------------------+
  *
- * XXX Why one overseer per CPU?  I did that originally to avoid
+ * XXX Why one dispatcher per CPU?  I did that originally to avoid
  * touching remote CPUs' memory when scheduling a job, but that still
  * requires interprocessor synchronization.  Perhaps we could get by
- * with a single overseer thread, at the expense of another pointer in
- * struct threadpool_job to identify the CPU on which it must run
- * in order for the overseer to schedule it correctly.
+ * with a single dispatcher thread, at the expense of another pointer
+ * in struct threadpool_job to identify the CPU on which it must run in
+ * order for the dispatcher to schedule it correctly.
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_threadpool.c,v 1.20 2021/01/13 02:19:08 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_threadpool.c,v 1.21 2021/01/13 02:20:15 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -141,27 +141,27 @@ SDT_PROBE_DEFINE2(sdt, kernel, threadpoo
     "struct threadpool *"/*pool*/, "struct threadpool_job *"/*job*/);
 SDT_PROBE_DEFINE2(sdt, kernel, threadpool, schedule__job__running,
     "struct threadpool *"/*pool*/, "struct threadpool_job *"/*job*/);
-SDT_PROBE_DEFINE2(sdt, kernel, threadpool, schedule__job__overseer,
+SDT_PROBE_DEFINE2(sdt, kernel, threadpool, schedule__job__dispatcher,
     "struct threadpool *"/*pool*/, "struct threadpool_job *"/*job*/);
 SDT_PROBE_DEFINE3(sdt, kernel, threadpool, schedule__job__thread,
     "struct threadpool *"/*pool*/,
     "struct threadpool_job *"/*job*/,
     "struct lwp *"/*thread*/);
 
-SDT_PROBE_DEFINE1(sdt, kernel, threadpool, overseer__start,
+SDT_PROBE_DEFINE1(sdt, kernel, threadpool, dispatcher__start,
     "struct threadpool *"/*pool*/);
-SDT_PROBE_DEFINE1(sdt, kernel, threadpool, overseer__dying,
+SDT_PROBE_DEFINE1(sdt, kernel, threadpool, dispatcher__dying,
     "struct threadpool *"/*pool*/);
-SDT_PROBE_DEFINE1(sdt, kernel, threadpool, overseer__spawn,
+SDT_PROBE_DEFINE1(sdt, kernel, threadpool, dispatcher__spawn,
     "struct threadpool *"/*pool*/);
-SDT_PROBE_DEFINE2(sdt, kernel, threadpool, overseer__race,
+SDT_PROBE_DEFINE2(sdt, kernel, threadpool, dispatcher__race,
     "struct threadpool *"/*pool*/,
     "struct threadpool_job *"/*job*/);
-SDT_PROBE_DEFINE3(sdt, kernel, threadpool, overseer__assign,
+SDT_PROBE_DEFINE3(sdt, kernel, threadpool, dispatcher__assign,
     "struct threadpool *"/*pool*/,
     "struct threadpool_job *"/*job*/,
     "struct lwp *"/*thread*/);
-SDT_PROBE_DEFINE1(sdt, kernel, threadpool, overseer__exit,
+SDT_PROBE_DEFINE1(sdt, kernel, threadpool, dispatcher__exit,
     "struct threadpool *"/*pool*/);
 
 SDT_PROBE_DEFINE1(sdt, kernel, threadpool, thread__start,
@@ -189,7 +189,7 @@ struct threadpool_thread {
 
 struct threadpool {
 	kmutex_t			tp_lock;
-	struct threadpool_thread	tp_overseer;
+	struct threadpool_thread	tp_dispatcher;
 	struct job_head			tp_jobs;
 	struct thread_head		tp_idle_threads;
 	uint64_t			tp_refcnt;
@@ -213,7 +213,7 @@ static threadpool_job_fn_t threadpool_jo
 static void	threadpool_job_hold(struct threadpool_job *);
 static void	threadpool_job_rele(struct threadpool_job *);
 
-static void	threadpool_overseer_thread(void *) __dead;
+static void	threadpool_dispatcher_thread(void *) __dead;
 static void	threadpool_thread(void *) __dead;
 
 static pool_cache_t	threadpool_thread_pc __read_mostly;
@@ -356,6 +356,18 @@ threadpools_init(void)
 	mutex_init(&threadpools_lock, MUTEX_DEFAULT, IPL_NONE);
 }
 
+static void
+threadnamesuffix(char *buf, size_t buflen, struct cpu_info *ci, int pri)
+{
+
+	buf[0] = '\0';
+	if (ci)
+		snprintf(buf + strlen(buf), buflen - strlen(buf), "/%d",
+		    cpu_index(ci));
+	if (pri != PRI_NONE)
+		snprintf(buf + strlen(buf), buflen - strlen(buf), "@%d", pri);
+}
+
 /* Thread pool creation */
 
 static bool
@@ -369,6 +381,7 @@ threadpool_create(struct threadpool *con
     pri_t pri)
 {
 	struct lwp *lwp;
+	char suffix[16];
 	int ktflags;
 	int error;
 
@@ -377,46 +390,46 @@ threadpool_create(struct threadpool *con
 	SDT_PROBE2(sdt, kernel, threadpool, create,  ci, pri);
 
 	mutex_init(&pool->tp_lock, MUTEX_DEFAULT, IPL_VM);
-	/* XXX overseer */
+	/* XXX dispatcher */
 	TAILQ_INIT(&pool->tp_jobs);
 	TAILQ_INIT(&pool->tp_idle_threads);
-	pool->tp_refcnt = 1;		/* overseer's reference */
+	pool->tp_refcnt = 1;		/* dispatcher's reference */
 	pool->tp_flags = 0;
 	pool->tp_cpu = ci;
 	pool->tp_pri = pri;
 
-	pool->tp_overseer.tpt_lwp = NULL;
-	pool->tp_overseer.tpt_pool = pool;
-	pool->tp_overseer.tpt_job = NULL;
-	cv_init(&pool->tp_overseer.tpt_cv, "poolover");
+	pool->tp_dispatcher.tpt_lwp = NULL;
+	pool->tp_dispatcher.tpt_pool = pool;
+	pool->tp_dispatcher.tpt_job = NULL;
+	cv_init(&pool->tp_dispatcher.tpt_cv, "pooldisp");
 
 	ktflags = 0;
 	ktflags |= KTHREAD_MPSAFE;
 	if (pri < PRI_KERNEL)
 		ktflags |= KTHREAD_TS;
-	error = kthread_create(pri, ktflags, ci, &threadpool_overseer_thread,
-	    &pool->tp_overseer, &lwp,
-	    "pooloverseer/%d@%d", (ci ? cpu_index(ci) : -1), (int)pri);
+	threadnamesuffix(suffix, sizeof(suffix), ci, pri);
+	error = kthread_create(pri, ktflags, ci, &threadpool_dispatcher_thread,
+	    &pool->tp_dispatcher, &lwp, "pooldisp%s", suffix);
 	if (error)
 		goto fail0;
 
 	mutex_spin_enter(&pool->tp_lock);
-	pool->tp_overseer.tpt_lwp = lwp;
-	cv_broadcast(&pool->tp_overseer.tpt_cv);
+	pool->tp_dispatcher.tpt_lwp = lwp;
+	cv_broadcast(&pool->tp_dispatcher.tpt_cv);
 	mutex_spin_exit(&pool->tp_lock);
 
 	SDT_PROBE3(sdt, kernel, threadpool, create__success,  ci, pri, pool);
 	return 0;
 
 fail0:	KASSERT(error);
-	KASSERT(pool->tp_overseer.tpt_job == NULL);
-	KASSERT(pool->tp_overseer.tpt_pool == pool);
+	KASSERT(pool->tp_dispatcher.tpt_job == NULL);
+	KASSERT(pool->tp_dispatcher.tpt_pool == pool);
 	KASSERT(pool->tp_flags == 0);
 	KASSERT(pool->tp_refcnt == 0);
 	KASSERT(TAILQ_EMPTY(&pool->tp_idle_threads));
 	KASSERT(TAILQ_EMPTY(&pool->tp_jobs));
-	KASSERT(!cv_has_waiters(&pool->tp_overseer.tpt_cv));
-	cv_destroy(&pool->tp_overseer.tpt_cv);
+	KASSERT(!cv_has_waiters(&pool->tp_dispatcher.tpt_cv));
+	cv_destroy(&pool->tp_dispatcher.tpt_cv);
 	mutex_destroy(&pool->tp_lock);
 	SDT_PROBE3(sdt, kernel, threadpool, create__failure,  ci, pri, error);
 	return error;
@@ -435,24 +448,24 @@ threadpool_destroy(struct threadpool *po
 	mutex_spin_enter(&pool->tp_lock);
 	KASSERT(TAILQ_EMPTY(&pool->tp_jobs));
 	pool->tp_flags |= THREADPOOL_DYING;
-	cv_broadcast(&pool->tp_overseer.tpt_cv);
+	cv_broadcast(&pool->tp_dispatcher.tpt_cv);
 	TAILQ_FOREACH(thread, &pool->tp_idle_threads, tpt_entry)
 		cv_broadcast(&thread->tpt_cv);
 	while (0 < pool->tp_refcnt) {
 		SDT_PROBE2(sdt, kernel, threadpool, destroy__wait,
 		    pool, pool->tp_refcnt);
-		cv_wait(&pool->tp_overseer.tpt_cv, &pool->tp_lock);
+		cv_wait(&pool->tp_dispatcher.tpt_cv, &pool->tp_lock);
 	}
 	mutex_spin_exit(&pool->tp_lock);
 
-	KASSERT(pool->tp_overseer.tpt_job == NULL);
-	KASSERT(pool->tp_overseer.tpt_pool == pool);
+	KASSERT(pool->tp_dispatcher.tpt_job == NULL);
+	KASSERT(pool->tp_dispatcher.tpt_pool == pool);
 	KASSERT(pool->tp_flags == THREADPOOL_DYING);
 	KASSERT(pool->tp_refcnt == 0);
 	KASSERT(TAILQ_EMPTY(&pool->tp_idle_threads));
 	KASSERT(TAILQ_EMPTY(&pool->tp_jobs));
-	KASSERT(!cv_has_waiters(&pool->tp_overseer.tpt_cv));
-	cv_destroy(&pool->tp_overseer.tpt_cv);
+	KASSERT(!cv_has_waiters(&pool->tp_dispatcher.tpt_cv));
+	cv_destroy(&pool->tp_dispatcher.tpt_cv);
 	mutex_destroy(&pool->tp_lock);
 }
 
@@ -472,7 +485,7 @@ threadpool_rele(struct threadpool *pool)
 	KASSERT(mutex_owned(&pool->tp_lock));
 	KASSERT(0 < pool->tp_refcnt);
 	if (--pool->tp_refcnt == 0)
-		cv_broadcast(&pool->tp_overseer.tpt_cv);
+		cv_broadcast(&pool->tp_dispatcher.tpt_cv);
 }
 
 /* Unbound thread pools */
@@ -859,10 +872,10 @@ threadpool_schedule_job(struct threadpoo
 	/* Otherwise, try to assign a thread to the job.  */
 	mutex_spin_enter(&pool->tp_lock);
 	if (__predict_false(TAILQ_EMPTY(&pool->tp_idle_threads))) {
-		/* Nobody's idle.  Give it to the overseer.  */
-		SDT_PROBE2(sdt, kernel, threadpool, schedule__job__overseer,
+		/* Nobody's idle.  Give it to the dispatcher.  */
+		SDT_PROBE2(sdt, kernel, threadpool, schedule__job__dispatcher,
 		    pool, job);
-		job->job_thread = &pool->tp_overseer;
+		job->job_thread = &pool->tp_dispatcher;
 		TAILQ_INSERT_TAIL(&pool->tp_jobs, job, job_entry);
 	} else {
 		/* Assign it to the first idle thread.  */
@@ -874,7 +887,7 @@ threadpool_schedule_job(struct threadpoo
 		job->job_thread->tpt_job = job;
 	}
 
-	/* Notify whomever we gave it to, overseer or idle thread.  */
+	/* Notify whomever we gave it to, dispatcher or idle thread.  */
 	KASSERT(job->job_thread != NULL);
 	cv_broadcast(&job->job_thread->tpt_cv);
 	mutex_spin_exit(&pool->tp_lock);
@@ -898,19 +911,19 @@ threadpool_cancel_job_async(struct threa
 	 *	   "luck of the draw").
 	 *
 	 *	=> "job" is not yet running, but is assigned to the
-	 *	   overseer.
+	 *	   dispatcher.
 	 *
 	 * When this happens, this code makes the determination that
 	 * the job is already running.  The failure mode is that the
 	 * caller is told the job is running, and thus has to wait.
-	 * The overseer will eventually get to it and the job will
+	 * The dispatcher will eventually get to it and the job will
 	 * proceed as if it had been already running.
 	 */
 
 	if (job->job_thread == NULL) {
 		/* Nothing to do.  Guaranteed not running.  */
 		return true;
-	} else if (job->job_thread == &pool->tp_overseer) {
+	} else if (job->job_thread == &pool->tp_dispatcher) {
 		/* Take it off the list to guarantee it won't run.  */
 		job->job_thread = NULL;
 		mutex_spin_enter(&pool->tp_lock);
@@ -945,15 +958,16 @@ threadpool_cancel_job(struct threadpool 
 		cv_wait(&job->job_cv, job->job_lock);
 }
 
-/* Thread pool overseer thread */
+/* Thread pool dispatcher thread */
 
 static void __dead
-threadpool_overseer_thread(void *arg)
+threadpool_dispatcher_thread(void *arg)
 {
-	struct threadpool_thread *const overseer = arg;
-	struct threadpool *const pool = overseer->tpt_pool;
+	struct threadpool_thread *const dispatcher = arg;
+	struct threadpool *const pool = dispatcher->tpt_pool;
 	struct lwp *lwp = NULL;
 	int ktflags;
+	char suffix[16];
 	int error;
 
 	KASSERT((pool->tp_cpu == NULL) || (pool->tp_cpu == curcpu()));
@@ -961,27 +975,27 @@ threadpool_overseer_thread(void *arg)
 
 	/* Wait until we're initialized.  */
 	mutex_spin_enter(&pool->tp_lock);
-	while (overseer->tpt_lwp == NULL)
-		cv_wait(&overseer->tpt_cv, &pool->tp_lock);
+	while (dispatcher->tpt_lwp == NULL)
+		cv_wait(&dispatcher->tpt_cv, &pool->tp_lock);
 
-	SDT_PROBE1(sdt, kernel, threadpool, overseer__start,  pool);
+	SDT_PROBE1(sdt, kernel, threadpool, dispatcher__start,  pool);
 
 	for (;;) {
 		/* Wait until there's a job.  */
 		while (TAILQ_EMPTY(&pool->tp_jobs)) {
 			if (ISSET(pool->tp_flags, THREADPOOL_DYING)) {
 				SDT_PROBE1(sdt, kernel, threadpool,
-				    overseer__dying,  pool);
+				    dispatcher__dying,  pool);
 				break;
 			}
-			cv_wait(&overseer->tpt_cv, &pool->tp_lock);
+			cv_wait(&dispatcher->tpt_cv, &pool->tp_lock);
 		}
 		if (__predict_false(TAILQ_EMPTY(&pool->tp_jobs)))
 			break;
 
 		/* If there are no threads, we'll have to try to start one.  */
 		if (TAILQ_EMPTY(&pool->tp_idle_threads)) {
-			SDT_PROBE1(sdt, kernel, threadpool, overseer__spawn,
+			SDT_PROBE1(sdt, kernel, threadpool, dispatcher__spawn,
 			    pool);
 			threadpool_hold(pool);
 			mutex_spin_exit(&pool->tp_lock);
@@ -991,17 +1005,17 @@ threadpool_overseer_thread(void *arg)
 			thread->tpt_lwp = NULL;
 			thread->tpt_pool = pool;
 			thread->tpt_job = NULL;
-			cv_init(&thread->tpt_cv, "poolthrd");
+			cv_init(&thread->tpt_cv, "pooljob");
 
 			ktflags = 0;
 			ktflags |= KTHREAD_MPSAFE;
 			if (pool->tp_pri < PRI_KERNEL)
 				ktflags |= KTHREAD_TS;
+			threadnamesuffix(suffix, sizeof(suffix), pool->tp_cpu,
+			    pool->tp_pri);
 			error = kthread_create(pool->tp_pri, ktflags,
 			    pool->tp_cpu, &threadpool_thread, thread, &lwp,
-			    "poolthread/%d@%d",
-			    (pool->tp_cpu ? cpu_index(pool->tp_cpu) : -1),
-			    (int)pool->tp_pri);
+			    "poolthread%s", suffix);
 
 			mutex_spin_enter(&pool->tp_lock);
 			if (error) {
@@ -1037,7 +1051,7 @@ threadpool_overseer_thread(void *arg)
 
 		mutex_enter(job->job_lock);
 		/* If the job was cancelled, we'll no longer be its thread.  */
-		if (__predict_true(job->job_thread == overseer)) {
+		if (__predict_true(job->job_thread == dispatcher)) {
 			mutex_spin_enter(&pool->tp_lock);
 			if (__predict_false(
 				    TAILQ_EMPTY(&pool->tp_idle_threads))) {
@@ -1046,7 +1060,7 @@ threadpool_overseer_thread(void *arg)
 				 * first.  We'll have to try again.
 				 */
 				SDT_PROBE2(sdt, kernel, threadpool,
-				    overseer__race,  pool, job);
+				    dispatcher__race,  pool, job);
 				TAILQ_INSERT_HEAD(&pool->tp_jobs, job,
 				    job_entry);
 			} else {
@@ -1058,7 +1072,7 @@ threadpool_overseer_thread(void *arg)
 				    TAILQ_FIRST(&pool->tp_idle_threads);
 
 				SDT_PROBE2(sdt, kernel, threadpool,
-				    overseer__assign,  job, thread->tpt_lwp);
+				    dispatcher__assign,  job, thread->tpt_lwp);
 				KASSERT(thread->tpt_job == NULL);
 				TAILQ_REMOVE(&pool->tp_idle_threads, thread,
 				    tpt_entry);
@@ -1076,7 +1090,7 @@ threadpool_overseer_thread(void *arg)
 	threadpool_rele(pool);
 	mutex_spin_exit(&pool->tp_lock);
 
-	SDT_PROBE1(sdt, kernel, threadpool, overseer__exit,  pool);
+	SDT_PROBE1(sdt, kernel, threadpool, dispatcher__exit,  pool);
 
 	kthread_exit(0);
 }

Reply via email to