xref: /freebsd/lib/libthr/libthr.3 (revision 7259ca31048e5ced8e7f90657a3d7084aeafdf51)
1.\" Copyright (c) 2005 Robert N. M. Watson
2.\" Copyright (c) 2014,2015,2021 The FreeBSD Foundation, Inc.
3.\" All rights reserved.
4.\"
5.\" Part of this documentation was written by
6.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship
7.\" from the FreeBSD Foundation.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.\" $FreeBSD$
31.\"
32.Dd October 1, 2021
33.Dt LIBTHR 3
34.Os
35.Sh NAME
36.Nm libthr
37.Nd "1:1 POSIX threads library"
38.Sh LIBRARY
39.Lb libthr
40.Sh SYNOPSIS
41.In pthread.h
42.Sh DESCRIPTION
43The
44.Nm
45library provides a 1:1 implementation of the
46.Xr pthread 3
47library interfaces for application threading.
48It
49has been optimized for use by applications expecting system scope thread
50semantics.
51.Pp
52The library is tightly integrated with the run-time link editor
53.Xr ld-elf.so.1 1
54and
55.Lb libc ;
56all three components must be built from the same source tree.
57Mixing
58.Li libc
59and
60.Nm
61libraries from different versions of
62.Fx
63is not supported.
64The run-time linker
65.Xr ld-elf.so.1 1
66has some code to ensure backward-compatibility with older versions of
67.Nm .
68.Pp
69The man page documents the quirks and tunables of the
70.Nm .
71When linking with
72.Li -lpthread ,
73the run-time dependency
74.Li libthr.so.3
75is recorded in the produced object.
76.Sh MUTEX ACQUISITION
77A locked mutex (see
78.Xr pthread_mutex_lock 3 )
79is represented by a volatile variable of type
80.Dv lwpid_t ,
81which records the global system identifier of the thread
82owning the lock.
83.Nm
84performs a contested mutex acquisition in three stages, each of which
85is more resource-consuming than the previous.
86The first two stages are only applied for a mutex of
87.Dv PTHREAD_MUTEX_ADAPTIVE_NP
88type and
89.Dv PTHREAD_PRIO_NONE
90protocol (see
91.Xr pthread_mutexattr 3 ) .
92.Pp
93First, on SMP systems, a spin loop
94is performed, where the library attempts to acquire the lock by
95.Xr atomic 9
96operations.
97The loop count is controlled by the
98.Ev LIBPTHREAD_SPINLOOPS
99environment variable, with a default value of 2000.
100.Pp
101If the spin loop
102was unable to acquire the mutex, a yield loop
103is executed, performing the same
104.Xr atomic 9
105acquisition attempts as the spin loop,
106but each attempt is followed by a yield of the CPU time
107of the thread using the
108.Xr sched_yield 2
109syscall.
110By default, the yield loop
111is not executed.
112This is controlled by the
113.Ev LIBPTHREAD_YIELDLOOPS
114environment variable.
115.Pp
116If both the spin and yield loops
117failed to acquire the lock, the thread is taken off the CPU and
118put to sleep in the kernel with the
119.Xr _umtx_op 2
120syscall.
121The kernel wakes up a thread and hands the ownership of the lock to
122the woken thread when the lock becomes available.
123.Sh THREAD STACKS
124Each thread is provided with a private user-mode stack area
125used by the C runtime.
126The size of the main (initial) thread stack is set by the kernel, and is
127controlled by the
128.Dv RLIMIT_STACK
129process resource limit (see
130.Xr getrlimit 2 ) .
131.Pp
132By default, the main thread's stack size is equal to the value of
133.Dv RLIMIT_STACK
134for the process.
135If the
136.Ev LIBPTHREAD_SPLITSTACK_MAIN
137environment variable is present in the process environment
138(its value does not matter),
139the main thread's stack is reduced to 4MB on 64bit architectures, and to
1402MB on 32bit architectures, when the threading library is initialized.
141The rest of the address space area which has been reserved by the
142kernel for the initial process stack is used for non-initial thread stacks
143in this case.
144The presence of the
145.Ev LIBPTHREAD_BIGSTACK_MAIN
146environment variable overrides
147.Ev LIBPTHREAD_SPLITSTACK_MAIN ;
148it is kept for backward-compatibility.
149.Pp
150The size of stacks for threads created by the process at run-time
151with the
152.Xr pthread_create 3
153call is controlled by thread attributes: see
154.Xr pthread_attr 3 ,
155in particular, the
156.Xr pthread_attr_setstacksize 3 ,
157.Xr pthread_attr_setguardsize 3
158and
159.Xr pthread_attr_setstackaddr 3
160functions.
161If no attributes for the thread stack size are specified, the default
162non-initial thread stack size is 2MB for 64bit architectures, and 1MB
163for 32bit architectures.
164.Sh RUN-TIME SETTINGS
165The following environment variables are recognized by
166.Nm
167and adjust the operation of the library at run-time:
168.Bl -tag -width "Ev LIBPTHREAD_SPLITSTACK_MAIN"
169.It Ev LIBPTHREAD_BIGSTACK_MAIN
170Disables the reduction of the initial thread stack enabled by
171.Ev LIBPTHREAD_SPLITSTACK_MAIN .
172.It Ev LIBPTHREAD_SPLITSTACK_MAIN
173Causes a reduction of the initial thread stack, as described in the
174section
175.Sx THREAD STACKS .
176This was the default behaviour of
177.Nm
178before
179.Fx 11.0 .
180.It Ev LIBPTHREAD_SPINLOOPS
181The integer value of the variable overrides the default count of
182iterations in the
183.Li spin loop
184of the mutex acquisition.
185The default count is 2000, set by the
186.Dv MUTEX_ADAPTIVE_SPINS
187constant in the
188.Nm
189sources.
190.It Ev LIBPTHREAD_YIELDLOOPS
191A non-zero integer value enables the yield loop
192in the process of the mutex acquisition.
193The value is the count of loop operations.
194.It Ev LIBPTHREAD_QUEUE_FIFO
195The integer value of the variable specifies how often blocked
196threads are inserted at the head of the sleep queue, instead of its tail.
197Bigger values reduce the frequency of the FIFO discipline.
198The value must be between 0 and 255.
199.Pp
200.El
201The following
202.Dv sysctl
203MIBs affect the operation of the library:
204.Bl -tag -width "Dv debug.umtx.robust_faults_verbose"
205.It Dv kern.ipc.umtx_vnode_persistent
206By default, a shared lock backed by a mapped file in memory is
207automatically destroyed on the last unmap of the corresponding file's page,
208which is allowed by POSIX.
209Setting the sysctl to 1 makes such a shared lock object persist until
210the vnode is recycled by the Virtual File System.
211Note that in case file is not opened and not mapped, the kernel might
212recycle it at any moment, making this sysctl less useful than it sounds.
213.It Dv kern.ipc.umtx_max_robust
214The maximal number of robust mutexes allowed for one thread.
215The kernel will not unlock more mutexes than specified, see
216.Xr _umtx_op
217for more details.
218The default value is large enough for most useful applications.
219.It Dv debug.umtx.robust_faults_verbose
220A non zero value makes kernel emit some diagnostic when the robust
221mutexes unlock was prematurely aborted after detecting some inconsistency,
222as a measure to prevent memory corruption.
223.El
224.Pp
225The
226.Dv RLIMIT_UMTXP
227limit (see
228.Xr getrlimit 2 )
229defines how many shared locks a given user may create simultaneously.
230.Sh INTERACTION WITH RUN-TIME LINKER
231On load,
232.Nm
233installs interposing handlers into the hooks exported by
234.Li libc .
235The interposers provide real locking implementation instead of the
236stubs for single-threaded processes in
237.Li libc ,
238cancellation support and some modifications to the signal operations.
239.Pp
240.Nm
241cannot be unloaded; the
242.Xr dlclose 3
243function does not perform any action when called with a handle for
244.Nm .
245One of the reasons is that the internal interposing of
246.Li libc
247functions cannot be undone.
248.Sh SIGNALS
249The implementation interposes the user-installed
250.Xr signal 3
251handlers.
252This interposing is done to postpone signal delivery to threads which
253entered (libthr-internal) critical sections, where the calling
254of the user-provided signal handler is unsafe.
255An example of such a situation is owning the internal library lock.
256When a signal is delivered while the signal handler cannot be safely
257called, the call is postponed and performed until after the exit from
258the critical section.
259This should be taken into account when interpreting
260.Xr ktrace 1
261logs.
262.Sh PROCESS-SHARED SYNCHRONIZATION OBJECTS
263In the
264.Li libthr
265implementation,
266user-visible types for all synchronization objects (e.g. pthread_mutex_t)
267are pointers to internal structures, allocated either by the corresponding
268.Fn pthread_<objtype>_init
269method call, or implicitly on first use when a static initializer
270was specified.
271The initial implementation of process-private locking object used this
272model with internal allocation, and the addition of process-shared objects
273was done in a way that did not break the application binary interface.
274.Pp
275For process-private objects, the internal structure is allocated using
276either
277.Xr malloc 3
278or, for
279.Xr pthread_mutex_init 3 ,
280an internal memory allocator implemented in
281.Nm .
282The internal allocator for mutexes is used to avoid bootstrap issues
283with many
284.Xr malloc 3
285implementations which need working mutexes to function.
286The same allocator is used for thread-specific data, see
287.Xr pthread_setspecific 3 ,
288for the same reason.
289.Pp
290For process-shared objects, the internal structure is created by first
291allocating a shared memory segment using
292.Xr _umtx_op 2
293operation
294.Dv UMTX_OP_SHM ,
295and then mapping it into process address space with
296.Xr mmap 2
297with the
298.Dv MAP_SHARED
299flag.
300The POSIX standard requires that:
301.Bd -literal
302only the process-shared synchronization object itself can be used for
303performing synchronization.  It need not be referenced at the address
304used to initialize it (that is, another mapping of the same object can
305be used).
306.Ed
307.Pp
308With the
309.Fx
310implementation, process-shared objects require initialization
311in each process that use them.
312In particular, if you map the shared memory containing the user portion of
313a process-shared object already initialized in different process, locking
314functions do not work on it.
315.Pp
316Another broken case is a forked child creating the object in memory shared
317with the parent, which cannot be used from parent.
318Note that processes should not use non-async-signal safe functions after
319.Xr fork 2
320anyway.
321.Sh SEE ALSO
322.Xr ktrace 1 ,
323.Xr ld-elf.so.1 1 ,
324.Xr getrlimit 2 ,
325.Xr errno 2 ,
326.Xr thr_exit 2 ,
327.Xr thr_kill 2 ,
328.Xr thr_kill2 2 ,
329.Xr thr_new 2 ,
330.Xr thr_self 2 ,
331.Xr thr_set_name 2 ,
332.Xr _umtx_op 2 ,
333.Xr dlclose 3 ,
334.Xr dlopen 3 ,
335.Xr getenv 3 ,
336.Xr pthread_attr 3 ,
337.Xr pthread_attr_setstacksize 3 ,
338.Xr pthread_create 3 ,
339.Xr signal 3 ,
340.Xr atomic 9
341.Sh HISTORY
342The
343.Nm
344library first appeared in
345.Fx 5.2 .
346.Sh AUTHORS
347.An -nosplit
348The
349.Nm
350library
351was originally created by
352.An Jeff Roberson Aq Mt jeff@FreeBSD.org ,
353and enhanced by
354.An Jonathan Mini Aq Mt mini@FreeBSD.org
355and
356.An Mike Makonnen Aq Mt mtm@FreeBSD.org .
357It has been substantially rewritten and optimized by
358.An David Xu Aq Mt davidxu@FreeBSD.org .
359