xref: /freebsd/lib/libthr/libthr.3 (revision be930504becc794c808b529bd65fa09d2d85f846)
1.\" Copyright (c) 2005 Robert N. M. Watson
2.\" Copyright (c) 2014 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 September 20, 2014
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, and can provide significant performance improvements
51compared to
52.Lb libkse .
53.Pp
54The library is tightly integrated with the run-time link editor
55.Xr ld-elf.so.1 1
56and
57.Lb libc ;
58all three components must be built from the same source tree.
59Mixing
60.Li libc
61and
62.Nm
63libraries from different versions of
64.Fx
65is not supported.
66The run-time linker
67.Xr ld-elf.so.1 1
68has some code to ensure backward-compatibility with older versions of
69.Nm .
70.Pp
71The man page documents the quirks and tunables of the
72.Nm .
73When linking with
74.Li -lpthread ,
75the run-time dependency
76.Li libthr.so.3
77is recorded in the produced object.
78.Sh MUTEX ACQUISITION
79A locked mutex (see
80.Xr pthread_mutex_lock 3 )
81is represented by a volatile variable of type
82.Dv lwpid_t ,
83which records the global system identifier of the thread
84owning the lock.
85.Nm
86performs a contested mutex acquisition in three stages, each of which
87is more resource-consuming than the previous.
88.Pp
89First, a spin loop
90is performed, where the library attempts to acquire the lock by
91.Xr atomic 9
92operations.
93The loop count is controlled by the
94.Ev LIBPTHREAD_SPINLOOPS
95environment variable, with a default value of 2000.
96.Pp
97If the spin loop
98was unable to acquire the mutex, a yield loop
99is executed, performing the same
100.Xr atomic 9
101acquisition attempts as the spin loop,
102but each attempt is followed by a yield of the CPU time
103of the thread using the
104.Xr sched_yield 2
105syscall.
106By default, the yield loop
107is not executed.
108This is controlled by the
109.Ev LIBPTHREAD_YIELDLOOPS
110environment variable.
111.Pp
112If both the spin and yield loops
113failed to acquire the lock, the thread is taken off the CPU and
114put to sleep in the kernel with the
115.Xr umtx 2
116syscall.
117The kernel wakes up a thread and hands the ownership of the lock to
118the woken thread when the lock becomes available.
119.Sh THREAD STACKS
120Each thread is provided with a private user-mode stack area
121used by the C runtime.
122The size of the main (initial) thread stack is set by the kernel, and is
123controlled by the
124.Dv RLIMIT_STACK
125process resource limit (see
126.Xr getrlimit 2 ) .
127.Pp
128By default, the main thread's stack size is equal to the value of
129.Dv RLIMIT_STACK
130for the process.
131If the
132.Ev LIBPTHREAD_SPLITSTACK_MAIN
133environment variable is present in the process environment
134(its value does not matter),
135the main thread's stack is reduced to 4MB on 64bit architectures, and to
1362MB on 32bit architectures, when the threading library is initialized.
137The rest of the address space area which has been reserved by the
138kernel for the initial process stack is used for non-initial thread stacks
139in this case.
140The presence of the
141.Ev LIBPTHREAD_BIGSTACK_MAIN
142environment variable overrides
143.Ev LIBPTHREAD_SPLITSTACK_MAIN ;
144it is kept for backward-compatibility.
145.Pp
146The size of stacks for threads created by the process at run-time
147with the
148.Xr pthread_create 3
149call is controlled by thread attributes: see
150.Xr pthread_attr 3 ,
151in particular, the
152.Xr pthread_attr_setstacksize 3 ,
153.Xr pthread_attr_setguardsize 3
154and
155.Xr pthread_attr_setstackaddr 3
156functions.
157If no attributes for the thread stack size are specified, the default
158non-initial thread stack size is 2MB for 64bit architectures, and 1MB
159for 32bit architectures.
160.Sh RUN-TIME SETTINGS
161The following environment variables are recognized by
162.Nm
163and adjust the operation of the library at run-time:
164.Bl -tag -width LIBPTHREAD_SPLITSTACK_MAIN
165.It Ev LIBPTHREAD_BIGSTACK_MAIN
166Disables the reduction of the initial thread stack enabled by
167.Ev LIBPTHREAD_SPLITSTACK_MAIN .
168.It Ev LIBPTHREAD_SPLITSTACK_MAIN
169Causes a reduction of the initial thread stack, as described in the
170section
171.Sx THREAD STACKS .
172This was the default behaviour of
173.Nm
174before
175.Fx 11.0 .
176.It Ev LIBPTHREAD_SPINLOOPS
177The integer value of the variable overrides the default count of
178iterations in the
179.Li spin loop
180of the mutex acquisition.
181The default count is 2000, set by the
182.Dv MUTEX_ADAPTIVE_SPINS
183constant in the
184.Nm
185sources.
186.It Ev LIBPTHREAD_YIELDLOOPS
187A non-zero integer value enables the yield loop
188in the process of the mutex acquisition.
189The value is the count of loop operations.
190.It Ev LIBPTHREAD_QUEUE_FIFO
191The integer value of the variable specifies how often blocked
192threads are inserted at the head of the sleep queue, instead of its tail.
193Bigger values reduce the frequency of the FIFO discipline.
194The value must be between 0 and 255.
195.El
196.Sh INTERACTION WITH RUN-TIME LINKER
197The
198.Nm
199library must appear before
200.Li libc
201in the global order of depended objects.
202.Pp
203Loading
204.Nm
205with the
206.Xr dlopen 3
207call in the process after the program binary is activated
208is not supported, and causes miscellaneous and hard-to-diagnose misbehaviour.
209This is due to
210.Nm
211interposing several important
212.Li libc
213symbols to provide thread-safe services.
214In particular,
215.Dv errno
216and the locking stubs from
217.Li libc
218are affected.
219This requirement is currently not enforced.
220.Pp
221If the program loads any modules at run-time, and those modules may require
222threading services, the main program binary must be linked with
223.Li libpthread ,
224even if it does not require any services from the library.
225.Pp
226.Nm
227cannot be unloaded; the
228.Xr dlclose 3
229function does not perform any action when called with a handle for
230.Nm .
231One of the reasons is that the interposing of
232.Li libc
233functions cannot be undone.
234.Sh SIGNALS
235The implementation also interposes the user-installed
236.Xr signal 3
237handlers.
238This interposing is done to postpone signal delivery to threads which
239entered (libthr-internal) critical sections, where the calling
240of the user-provided signal handler is unsafe.
241An example of such a situation is owning the internal library lock.
242When a signal is delivered while the signal handler cannot be safely
243called, the call is postponed and performed until after the exit from
244the critical section.
245This should be taken into account when interpreting
246.Xr ktrace 1
247logs.
248.Sh SEE ALSO
249.Xr ktrace 1 ,
250.Xr ld-elf.so.1 1 ,
251.Xr getrlimit 2 ,
252.Xr umtx 2 ,
253.Xr dlclose 3 ,
254.Xr dlopen 3 ,
255.Xr errno 3 ,
256.Xr getenv 3 ,
257.Xr libc 3 ,
258.Xr pthread_attr 3 ,
259.Xr pthread_attr_setstacksize 3 ,
260.Xr pthread_create 3 ,
261.Xr signal 3 ,
262.Xr atomic 9
263.Sh AUTHORS
264.An -nosplit
265The
266.Nm
267library
268was originally created by
269.An Jeff Roberson Aq Mt jeff@FreeBSD.org ,
270and enhanced by
271.An Jonathan Mini Aq Mt mini@FreeBSD.org
272and
273.An Mike Makonnen Aq Mt mtm@FreeBSD.org .
274It has been substantially rewritten and optimized by
275.An David Xu Aq Mt davidxu@FreeBSD.org .
276