git: 4472a048cf95 - main - libthr: GC pshared locks not more than each 25msecs by default
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 27 Sep 2026 23:51:12 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=4472a048cf95c9c1593a8b04655a59096b44b0c9
commit 4472a048cf95c9c1593a8b04655a59096b44b0c9
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-09-27 22:16:33 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-09-27 22:30:00 +0000
libthr: GC pshared locks not more than each 25msecs by default
Provide a tunable env variable to request immediate GC on destroy
to allow to return to the previous behavior.
Based on the report and patch by Atle Solbakken <atle.solbakken@gmail.com>.
PR: 268532
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
---
lib/libthr/thread/thr_init.c | 3 +++
lib/libthr/thread/thr_private.h | 1 +
lib/libthr/thread/thr_pshared.c | 25 ++++++++++++++++++++++---
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c
index 0f9e3749d75f..162ef7dfe7a9 100644
--- a/lib/libthr/thread/thr_init.c
+++ b/lib/libthr/thread/thr_init.c
@@ -539,6 +539,9 @@ init_private(void)
mint, NULL, NULL);
}
}
+ env = getenv("LIBPTHREAD_PSHARED_LOCK_DESTROY_IMMEDIATE_GC");
+ if (env)
+ __thr_pshared_destroy_imm_gc = true;
}
init_once = 1;
}
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index d7b889930365..2edf09d761ae 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -780,6 +780,7 @@ extern struct pthread *_single_thread __hidden;
extern bool _thr_after_fork __hidden;
extern int __thr_new_flags;
+extern bool __thr_pshared_destroy_imm_gc __hidden;
/*
* Function prototype definitions.
diff --git a/lib/libthr/thread/thr_pshared.c b/lib/libthr/thread/thr_pshared.c
index d20d66e21ea3..698cc5e6adc7 100644
--- a/lib/libthr/thread/thr_pshared.c
+++ b/lib/libthr/thread/thr_pshared.c
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/queue.h>
+#include <sys/time.h>
#include "namespace.h"
#include <stdlib.h>
#include "un-namespace.h"
@@ -49,6 +50,10 @@ static struct pshared_hash_head pshared_hash[HASH_SIZE];
static struct urwlock pshared_lock = DEFAULT_URWLOCK;
static int page_size;
+#define GC_INTERVAL_USEC 25000
+static struct timeval pshared_gc_time = {0, 0};
+bool __thr_pshared_destroy_imm_gc = false;
+
void
__thr_pshared_init(void)
{
@@ -94,9 +99,8 @@ pshared_unlock(struct pthread *curthread)
* mapped off-page.
*
* Mitigate the problem by checking the liveness of all hashed keys
- * periodically. Right now this is executed on each
- * pthread_lock_destroy(), but may be done less often if found to be
- * too time-consuming.
+ * periodically. Right now this is executed on pthread_lock_destroy()
+ * if previous gc happen later than 25msecs.
*/
static void
pshared_gc(struct pthread *curthread)
@@ -104,8 +108,18 @@ pshared_gc(struct pthread *curthread)
struct pshared_hash_head *hd;
struct psh *h, *h1;
int error, i;
+ struct timeval now, diff;
pshared_wlock(curthread);
+
+ if (!__thr_pshared_destroy_imm_gc && gettimeofday(&now, NULL) == 0) {
+ timersub(&now, &pshared_gc_time, &diff);
+ if (diff.tv_sec == 0 && diff.tv_usec < GC_INTERVAL_USEC) {
+ pshared_unlock(curthread);
+ return;
+ }
+ }
+
for (i = 0; i < HASH_SIZE; i++) {
hd = &pshared_hash[i];
LIST_FOREACH_SAFE(h, hd, link, h1) {
@@ -118,6 +132,11 @@ pshared_gc(struct pthread *curthread)
free(h);
}
}
+
+ if (!__thr_pshared_destroy_imm_gc && gettimeofday(&now, NULL) == 0) {
+ pshared_gc_time = now;
+ }
+
pshared_unlock(curthread);
}