Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Nov 2020 19:20:58 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r367693 - head/sys/kern
Message-ID:  <202011141920.0AEJKwjD052066@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Sat Nov 14 19:20:58 2020
New Revision: 367693
URL: https://svnweb.freebsd.org/changeset/base/367693

Log:
  thread: rework tid batch to use helpers

Modified:
  head/sys/kern/kern_thread.c

Modified: head/sys/kern/kern_thread.c
==============================================================================
--- head/sys/kern/kern_thread.c	Sat Nov 14 19:20:37 2020	(r367692)
+++ head/sys/kern/kern_thread.c	Sat Nov 14 19:20:58 2020	(r367693)
@@ -259,6 +259,54 @@ tid_free_batch(lwpid_t *batch, int n)
 }
 
 /*
+ * Batching for thread reapping.
+ */
+struct tidbatch {
+	lwpid_t tab[16];
+	int n;
+};
+
+static void
+tidbatch_prep(struct tidbatch *tb)
+{
+
+	tb->n = 0;
+}
+
+static void
+tidbatch_add(struct tidbatch *tb, struct thread *td)
+{
+
+	KASSERT(tb->n < nitems(tb->tab),
+	    ("%s: count too high %d", __func__, tb->n));
+	tb->tab[tb->n] = td->td_tid;
+	tb->n++;
+}
+
+static void
+tidbatch_process(struct tidbatch *tb)
+{
+
+	KASSERT(tb->n <= nitems(tb->tab),
+	    ("%s: count too high %d", __func__, tb->n));
+	if (tb->n == nitems(tb->tab)) {
+		tid_free_batch(tb->tab, tb->n);
+		tb->n = 0;
+	}
+}
+
+static void
+tidbatch_final(struct tidbatch *tb)
+{
+
+	KASSERT(tb->n <= nitems(tb->tab),
+	    ("%s: count too high %d", __func__, tb->n));
+	if (tb->n != 0) {
+		tid_free_batch(tb->tab, tb->n);
+	}
+}
+
+/*
  * Prepare a thread for use.
  */
 static int
@@ -487,8 +535,8 @@ void
 thread_reap(void)
 {
 	struct thread *itd, *ntd;
-	lwpid_t tidbatch[16];
-	int tidbatchn;
+	struct tidbatch tidbatch;
+	int tdcount;
 
 	/*
 	 * Reading upfront is pessimal if followed by concurrent atomic_swap,
@@ -499,24 +547,29 @@ thread_reap(void)
 
 	itd = (struct thread *)atomic_swap_ptr((uintptr_t *)&thread_zombies,
 	    (uintptr_t)NULL);
-	tidbatchn = 0;
+	if (itd == NULL)
+		return;
+
+	tidbatch_prep(&tidbatch);
+	tdcount = 0;
 	while (itd != NULL) {
 		ntd = itd->td_zombie;
-		tidbatch[tidbatchn] = itd->td_tid;
-		tidbatchn++;
+		EVENTHANDLER_DIRECT_INVOKE(thread_dtor, itd);
+		tidbatch_add(&tidbatch, itd);
 		thread_cow_free(itd);
 		thread_free_batched(itd);
-		if (tidbatchn == nitems(tidbatch)) {
-			tid_free_batch(tidbatch, tidbatchn);
-			thread_count_sub(tidbatchn);
-			tidbatchn = 0;
+		tidbatch_process(&tidbatch);
+		tdcount++;
+		if (tdcount == 32) {
+			thread_count_sub(tdcount);
+			tdcount = 0;
 		}
 		itd = ntd;
 	}
 
-	if (tidbatchn != 0) {
-		tid_free_batch(tidbatch, tidbatchn);
-		thread_count_sub(tidbatchn);
+	tidbatch_final(&tidbatch);
+	if (tdcount != 0) {
+		thread_count_sub(tdcount);
 	}
 }
 
@@ -567,7 +620,6 @@ static void
 thread_free_batched(struct thread *td)
 {
 
-	EVENTHANDLER_DIRECT_INVOKE(thread_dtor, td);
 	lock_profile_thread_exit(td);
 	if (td->td_cpuset)
 		cpuset_rel(td->td_cpuset);
@@ -588,6 +640,7 @@ thread_free(struct thread *td)
 {
 	lwpid_t tid;
 
+	EVENTHANDLER_DIRECT_INVOKE(thread_dtor, td);
 	tid = td->td_tid;
 	thread_free_batched(td);
 	tid_free(tid);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011141920.0AEJKwjD052066>