%other-pointer-widetag derive-type: derive for simple-array.
[sbcl.git] / src / code / thread-structs.lisp
blob98b0f465af883d3641b1db84dd4c93009671d0bb
1 ;;;; support for threads needed at cross-compile time
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB-THREAD")
14 ;;; An AVL tree of threads keyed by 'struct thread'. NIL is the empty tree.
15 (sb-ext:define-load-time-global *all-threads* ())
16 ;;; Next TLS index to use. This is shifted by n-fixnum-tag-bits because it holds
17 ;;; a word-aligned raw integer, not a fixnum (but it looks like a fixnum)
18 (sb-ext:define-load-time-global sb-vm::*free-tls-index* 0)
20 ;;; It's possible to make futex/non-futex switchable at runtime by ensuring that
21 ;;; these synchronization primitive structs contain all the slots for the union
22 ;;; of any kind of backing object. Some of the #+sb-futex/#-sb-futex cases in
23 ;;; target-thread also have to be changed to a COND rather than a compile-time test.
24 ;;; Among the uses of this would be to test real posix mutexes (with a finalizer on
25 ;;; each lisp-side proxy) or support older C APIs. Posix mutexes work nicely now
26 ;;; because finalizers are more efficient than they were, and when many threads
27 ;;; compete for a mutex, the pthread code seems to do a better job at reducing
28 ;;; cycles spent in the OS.
30 (sb-xc:defstruct (mutex (:constructor make-mutex (&key name))
31 (:copier nil))
32 "Mutex type."
33 #+sb-futex (state 0 :type sb-vm:word)
34 ;; If adding slots between STATE and NAME, please see futex_name() in linux_os.c
35 ;; which attempts to divine a string from a futex word address.
36 (name nil :type (or null simple-string))
37 ;; The owner is a non-pointer so that GC pages containing mutexes do not get dirtied
38 ;; with mutex ownership change. The natural representation of this is SB-VM:WORD
39 ;; but the "funny fixnum" representation - i.e. N_WORD_BITS bits of significance, but
40 ;; cast as fixnum when read - avoids consing on 32-bit builds, and also not all of them
41 ;; implement RAW-INSTANCE-CAS which would be otherwise needed.
42 (%owner 0 :type fixnum))
44 (sb-xc:defstruct (waitqueue (:copier nil) (:constructor make-waitqueue (&key name)))
45 "Waitqueue type."
46 ;; futex words are actually 32-bits, but it needs to be a raw slot and we don't have
47 ;; 32-bit raw slots on 64-bit machines.
48 #+sb-futex (token 0 :type sb-ext:word)
49 ;; If adding slots between TOKEN and NAME, please see futex_name() in linux_os.c
50 ;; which attempts to divine a string from a futex word address.
51 (name nil :type (or null string))
52 ;; For WITH-CAS-LOCK: because CONDITION-WAIT must be able to call
53 ;; %WAITQUEUE-WAKEUP without re-aquiring the mutex, we need a separate
54 ;; lock. In most cases this should be uncontested thanks to the mutex --
55 ;; the only case where that might not be true is when CONDITION-WAIT
56 ;; unwinds and %WAITQUEUE-DROP is called.
57 . #+sb-futex nil
58 #-sb-futex (%owner %head %tail))
60 (sb-xc:defstruct (semaphore (:copier nil)
61 (:constructor %make-semaphore (%count mutex queue)))
62 "Semaphore type. The fact that a SEMAPHORE is a STRUCTURE-OBJECT
63 should be considered an implementation detail, and may change in the
64 future."
65 (%count 0 :type (integer 0))
66 (waitcount 0 :type sb-vm:word)
67 (mutex nil :read-only t :type mutex)
68 (queue nil :read-only t :type waitqueue))
70 (declaim (sb-ext:freeze-type waitqueue semaphore))
72 (sb-ext:define-load-time-global *profiled-threads* :all)
73 (declaim (type (or (eql :all) list) *profiled-threads*))
75 (sb-xc:defstruct (thread (:constructor %make-thread (%name %ephemeral-p semaphore))
76 (:copier nil))
77 "Thread type. Do not rely on threads being structs as it may change
78 in future versions."
79 (%name nil :type (or null simple-string)) ; C code could read this
80 (%ephemeral-p nil :type boolean :read-only t)
81 ;; This is one of a few different views of a lisp thread:
82 ;; 1. the memory space (thread->os_addr in C)
83 ;; 2. 'struct thread' at some offset into the memory space, coinciding
84 ;; with the SB-VM::THREAD primitive object
85 ;; 3. a pthread, which may reside anywhere, possibly the high end of the lisp stack
86 ;; (above the SP given to your entrypoint), whatever the pthread library chooses.
87 ;; 4. the THREAD instance (this structure)
88 ;; This value is 0 if the thread is not considered alive, though the pthread
89 ;; may be running its termination code (unlinking from all_threads etc)
90 (primitive-thread 0 :type sb-vm:word)
91 ;; This is a redundant copy of the pthread identifier from the primitive thread.
92 ;; It's needed in the SB-THREAD:THREAD as well because there are valid reasons to
93 ;; manipulate the new thread before it has assigned 'th->os_thread = pthread_self()'.
94 ;; While we always have access to the C struct thread from Lisp, apparently the C
95 ;; code can't pass "&th->os_thread" as the first argument to pthread_create() for the
96 ;; incredible reason that the word might be written *after* the memory pointed at
97 ;; by 'th' has already been freed. Such action might seem to violate:
98 ;; "Before returning, a successful call to pthread_create() stores the ID of the
99 ;; new thread in the buffer pointed to by thread"
100 ;; (https://man7.org/linux/man-pages/man3/pthread_create.3.html)
101 ;; but that's not exactly what POSIX says, which is only:
102 ;; "Upon successful completion, pthread_create() stores the ID of the created thread
103 ;; in the location referenced by thread."
104 ;; (https://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_create.html)
105 ;; so there seems to be some leeway, and linux + glibc provides more of a guarantee.
106 ;; Technically we should have only one authoritative source of the pthread identifier,
107 ;; but it's not too critical, it's just annoying that there are two sources of
108 ;; the same value.
109 ;; The slot is somewhat poorly named (for consistency with C) because though it may
110 ;; correspond to an OS thread, it could be the case that the threading model has
111 ;; user-visible threads that do not map directly to OSs threads (or LWPs).
112 ;; Any use of THREAD-OS-THREAD from lisp should take care to ensure validity of
113 ;; the thread id by holding the INTERRUPTIONS-LOCK.
114 ;; Not needed for win32 threads.
115 #-win32 (os-thread 0 :type sb-vm:word)
116 ;; Keep a copy of the stack range for use in SB-EXT:STACK-ALLOCATED-P so that
117 ;; we don't have to read it from the primitive thread which is unsafe for any
118 ;; thread other than the current thread.
119 ;; Usually this is a fixed amount below PRIMITIVE-THREAD, but the exact offset
120 ;; varies by build configuration, and if #+win32 it is not related in any way.
121 (control-stack-start 0 :type sb-vm:word)
122 (control-stack-end 0 :type sb-vm:word)
123 ;; At the beginning of the thread's life, this is a vector of data required
124 ;; to start the user code. At the end, is it pointer to the 'struct thread'
125 ;; so that it can be either freed or reused.
126 (startup-info 0 :type (or fixnum (simple-vector 6)))
127 ;; Whether this thread should be returned in LIST-ALL-THREADS.
128 ;; This is almost-but-not-quite the same as what formerly
129 ;; might have been known as the %ALIVE-P flag.
130 (%visible 1 :type fixnum)
131 (interruptions nil :type list)
132 (interruptions-lock
133 (make-mutex :name "thread interruptions lock")
134 :type mutex :read-only t)
136 ;; Per-thread memoization of GET-INTERNAL-REAL-TIME, for race-free update.
137 ;; This might be a bignum, which is why we bother.
138 #-64-bit (observed-internal-real-time-delta-sec 0 :type sb-vm:word)
139 #-64-bit (observed-internal-real-time-delta-millisec
140 ;; This needs a sentinel that can not possibly match an actual delta.
141 ;; I have seen threads start up where 0 and 0 do match sec,msec
142 ;; respectively, and then we'd return the cached NIL as if it were
143 ;; the time. Forcing mismatch avoids putting in an extra test for NIL.
144 (ash sb-ext:most-positive-word -1)
145 :type sb-vm:signed-word)
146 #-64-bit (internal-real-time)
148 (max-stw-pause 0 :type sb-vm:word) ; microseconds
149 (sum-stw-pause 0 :type sb-vm:word) ; "
150 (ct-stw-pauses 0 :type sb-vm:word) ; to compute the avg
152 ;; On succesful execution of the thread's lambda, a list of values.
153 (result 0)
154 ;; The completion condition _could_ be manifested as a condition var, but a difficulty
155 ;; in doing so is that condition vars can always experience a spurious wakeup.
156 ;; Dealing with timeouts becomes troublesome then. But we can utilize the fact that
157 ;; WAIT-ON-SEMPAHORE implements a timeout, though as its comment says, the timeout
158 ;; doesn't account for re-acquiring the internal mutex if that takes nontrivial time,
159 ;; which it shouldn't since it guards very little work.
160 ;; At any rate, the semaphore abstraction is never subject to spurious wakeup.
161 (semaphore nil :type (or null semaphore))
162 waiting-for)
164 (sb-xc:defstruct (foreign-thread
165 (:copier nil)
166 (:include thread (%name "callback"))
167 (:constructor make-foreign-thread ())
168 (:conc-name "THREAD-"))
169 "Type of native threads which are attached to the runtime as Lisp threads
170 temporarily.")
172 (declaim (sb-ext:freeze-type mutex thread))
173 #-sb-xc-host
174 (progn
175 (defvar *current-thread*)
176 (declaim (type thread *current-thread*)))