Add some remarks and a utility function

This commit is contained in:
Douglas Katzman 2026-04-30 18:44:54 -04:00
parent 84d5a7b46b
commit 9b67e9100d
4 changed files with 34 additions and 0 deletions

View file

@ -13,6 +13,7 @@
;;; symbols to protect from tree-shaker, for some tests
(export '(%thread-local-references
%thread-from-tid
get-spinlock
release-spinlock
spinlock
@ -294,6 +295,13 @@ an error in that case."
(let ((new (avl-insert old addr ,thread)))
(when (eq old (setq old (sb-ext:cas *all-threads* old new))) (return)))))))
(defun %thread-from-tid (os-tid)
(declare (type (unsigned-byte 32) os-tid))
(avltree-filter (lambda (node &aux (thread (avlnode-data node)))
(when (= (thread-os-tid thread) os-tid)
(return-from %thread-from-tid thread)))
*all-threads*))
(defun vmthread-name (vmthread)
(binding* ((node (avl-find (vmthread-id->addr vmthread) *all-threads*) :exit-if-null)
(thread (avlnode-data node) :exit-if-null)

View file

@ -27,6 +27,18 @@
;;; compete for a mutex, the pthread code seems to do a better job at reducing
;;; cycles spent in the OS.
;;; Mutexes could be equipped with telemetry compatible with absl::Mutex.
;;; Specifically, we'd like to know the "Induced wait" which is the sum of CPU cycles
;;; a lock owner caused other threads to wait. It's tricky to report because measurement
;;; is performed in the waiting thread (the "victim" of wait) but reporting should occur
;;; in the "culprit" thread so that the call stack accurately reflects the function
;;; whose fault it is that there was induced wait time. absl mutex can do this because
;;; it is acutely aware of the queue of waiters, and it knows which waiter it wakes.
;;; SBCL mutex can't, because we defer everything to the OS. But the delay time can be
;;; handed off to -some- waker using a slot of the mutex, which stastically should result
;;; in the right effect. To keep struct size unchanged, the owner ID and futex word
;;; must be packed into a single raw slot. (None of this is implemented yet!)
(sb-xc:defstruct (mutex (:constructor make-mutex (&key name))
(:copier nil))
"Mutex type."
@ -110,6 +122,14 @@ in future versions."
;; This value is 0 if the thread is not considered alive, though the pthread
;; may be running its termination code (unlinking from all_threads etc)
(primitive-thread 0 :type sb-vm:word)
;; It is absolutely critical that our OS thread identifiers take no more than 32 bits
;; if #+sb-futex is present. So don't go changing this slot just because you feel like.
;; * macOS (mach_port_t): unsigned int
;; * FreeBSD (thr_self): thr_self writes a long to its its pointer arg,
;; however LWP IDs occupy a smaller range that can be cast to int
;; * NetBSD (_lwp_self): lwpid_t which is int32_t
;; * Linux (gettid): 32-bit pid_t
;; * Windows (GetCurrentThreadId): 32-bit DWORD
;; Caution: the identified thread may have exited by the time you've read this slot
(os-tid 0 :type (unsigned-byte 32) :read-only t)
;; This is a redundant copy of the pthread identifier from the primitive thread.

View file

@ -24,6 +24,7 @@
#include "gc.h"
// Allegedly this could use thr_self() or _lwp_self() both of which are 32-bit
int sb_GetTID() { return 0; } // this doesn't affect anything
void os_init() {}

View file

@ -317,3 +317,8 @@
(assert (string= (first results) "newname"))
(assert (find "finalizer" (second results) :test 'string=))
(assert (find "testme" (second results) :test 'string=)))))
(with-test (:name :thread-from-tid)
(let ((tid (sb-thread:thread-os-tid *current-thread*)))
(when (plusp tid) ; SunOS returns 0
(assert (eq (sb-thread:%thread-from-tid tid) *current-thread*)))))