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