Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
LIBTHR(3)	       FreeBSD Library Functions Manual		     LIBTHR(3)

     libthr -- 1:1 POSIX threads library

     1:1 Threading Library (libthr, -lthr)

     #include <pthread.h>

     The libthr	library	provides a 1:1 implementation of the pthread(3)
     library interfaces	for application	threading.  It has been	optimized for
     use by applications expecting system scope	thread semantics.

     The library is tightly integrated with the	run-time link editor and	Standard C Library (libc, -lc);	all three components
     must be built from	the same source	tree.  Mixing libc and libthr
     libraries from different versions of FreeBSD is not supported.  The run-
     time linker	has some code to ensure	backward-compatibility
     with older	versions of libthr.

     The man page documents the	quirks and tunables of the libthr.  When link-
     ing with -lpthread, the run-time dependency is	recorded in
     the produced object.

     A locked mutex (see pthread_mutex_lock(3))	is represented by a volatile
     variable of type lwpid_t, which records the global	system identifier of
     the thread	owning the lock.  libthr performs a contested mutex acquisi-
     tion in three stages, each	of which is more resource-consuming than the
     previous.	The first two stages are only applied for a mutex of

     First, on SMP systems, a spin loop	is performed, where the	library
     attempts to acquire the lock by atomic(9) operations.  The	loop count is
     controlled	by the LIBPTHREAD_SPINLOOPS environment	variable, with a
     default value of 2000.

     If	the spin loop was unable to acquire the	mutex, a yield loop is exe-
     cuted, performing the same	atomic(9) acquisition attempts as the spin
     loop, but each attempt is followed	by a yield of the CPU time of the
     thread using the sched_yield(2) syscall.  By default, the yield loop is
     not executed.  This is controlled by the LIBPTHREAD_YIELDLOOPS environ-
     ment variable.

     If	both the spin and yield	loops failed to	acquire	the lock, the thread
     is	taken off the CPU and put to sleep in the kernel with the _umtx_op(2)
     syscall.  The kernel wakes	up a thread and	hands the ownership of the
     lock to the woken thread when the lock becomes available.

     Each thread is provided with a private user-mode stack area used by the C
     runtime.  The size	of the main (initial) thread stack is set by the ker-
     nel, and is controlled by the RLIMIT_STACK	process	resource limit (see

     By	default, the main thread's stack size is equal to the value of
     RLIMIT_STACK for the process.  If the LIBPTHREAD_SPLITSTACK_MAIN environ-
     ment variable is present in the process environment (its value does not
     matter), the main thread's	stack is reduced to 4MB	on 64bit architec-
     tures, and	to 2MB on 32bit	architectures, when the	threading library is
     initialized.  The rest of the address space area which has	been reserved
     by	the kernel for the initial process stack is used for non-initial
     thread stacks in this case.  The presence of the LIBPTHREAD_BIGSTACK_MAIN
     environment variable overrides LIBPTHREAD_SPLITSTACK_MAIN;	it is kept for

     The size of stacks	for threads created by the process at run-time with
     the pthread_create(3) call	is controlled by thread	attributes: see
     pthread_attr(3), in particular, the pthread_attr_setstacksize(3),
     pthread_attr_setguardsize(3) and pthread_attr_setstackaddr(3) functions.
     If	no attributes for the thread stack size	are specified, the default
     non-initial thread	stack size is 2MB for 64bit architectures, and 1MB for
     32bit architectures.

     The following environment variables are recognized	by libthr and adjust
     the operation of the library at run-time:

     LIBPTHREAD_BIGSTACK_MAIN	    Disables the reduction of the initial
				    thread stack enabled by

     LIBPTHREAD_SPLITSTACK_MAIN	    Causes a reduction of the initial thread
				    stack, as described	in the section THREAD
				    STACKS.  This was the default behaviour of
				    libthr before FreeBSD 11.0.

     LIBPTHREAD_SPINLOOPS	    The	integer	value of the variable over-
				    rides the default count of iterations in
				    the	spin loop of the mutex acquisition.
				    The	default	count is 2000, set by the
				    MUTEX_ADAPTIVE_SPINS constant in the
				    libthr sources.

     LIBPTHREAD_YIELDLOOPS	    A non-zero integer value enables the yield
				    loop in the	process	of the mutex acquisi-
				    tion.  The value is	the count of loop

     LIBPTHREAD_QUEUE_FIFO	    The	integer	value of the variable speci-
				    fies how often blocked threads are
				    inserted at	the head of the	sleep queue,
				    instead of its tail.  Bigger values	reduce
				    the	frequency of the FIFO discipline.  The
				    value must be between 0 and	255.

     The following sysctl MIBs affect the operation of the library:

     kern.ipc.umtx_vnode_persistent	  By default, a	shared lock backed by
					  a mapped file	in memory is automati-
					  cally	destroyed on the last unmap of
					  the corresponding file's page, which
					  is allowed by	POSIX.	Setting	the
					  sysctl to 1 makes such a shared lock
					  object persist until the vnode is
					  recycled by the Virtual File System.
					  Note that in case file is not	opened
					  and not mapped, the kernel might
					  recycle it at	any moment, making
					  this sysctl less useful than it

     kern.ipc.umtx_max_robust		  The maximal number of	robust mutexes
					  allowed for one thread.  The kernel
					  will not unlock more mutexes than
					  specified, see _umtx_op for more
					  details.  The	default	value is large
					  enough for most useful applications.

     debug.umtx.robust_faults_verbose	  A non	zero value makes kernel	emit
					  some diagnostic when the robust
					  mutexes unlock was prematurely
					  aborted after	detecting some incon-
					  sistency, as a measure to prevent
					  memory corruption.

     The RLIMIT_UMTXP limit (see getrlimit(2)) defines how many	shared locks a
     given user	may create simultaneously.

     On	load, libthr installs interposing handlers into	the hooks exported by
     libc.  The	interposers provide real locking implementation	instead	of the
     stubs for single-threaded processes in libc, cancellation support and
     some modifications	to the signal operations.

     libthr cannot be unloaded;	the dlclose(3) function	does not perform any
     action when called	with a handle for libthr.  One of the reasons is that
     the internal interposing of libc functions	cannot be undone.

     The implementation	interposes the user-installed signal(3)	handlers.
     This interposing is done to postpone signal delivery to threads which
     entered (libthr-internal) critical	sections, where	the calling of the
     user-provided signal handler is unsafe.  An example of such a situation
     is	owning the internal library lock.  When	a signal is delivered while
     the signal	handler	cannot be safely called, the call is postponed and
     performed until after the exit from the critical section.	This should be
     taken into	account	when interpreting ktrace(1) logs.

     ktrace(1),,	getrlimit(2), errno(2),	thr_exit(2),
     thr_kill(2), thr_kill2(2),	thr_new(2), thr_self(2), thr_set_name(2),
     _umtx_op(2), dlclose(3), dlopen(3), getenv(3), pthread_attr(3),
     pthread_attr_setstacksize(3), pthread_create(3), signal(3), atomic(9)

     The libthr	library	was originally created by Jeff Roberson
     <>, and enhanced by Jonathan Mini <> and
     Mike Makonnen <>.  It has been substantially rewritten and
     optimized by David	Xu <>.

FreeBSD	Ports 11.2		 May 17, 2016		    FreeBSD Ports 11.2


Want to link to this manual page? Use this URL:

home | help