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

FreeBSD Manual Pages

  
 
  

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

NAME
       libthr -- 1:1 POSIX threads library

LIBRARY
       1:1 Threading Library (libthr, -lthr)

SYNOPSIS
       #include	<pthread.h>

DESCRIPTION
       The  libthr library provides a 1:1 implementation of the	pthread(3) li-
       brary 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
       ld-elf.so.1(1) and Standard C Library (libc, -lc); all three components
       must be built from the same source tree.	 Together, they	constitute the
       base C runtime environment of FreeBSD, running on top  of  the  FreeBSD
       kernel.

       Mixing  libc and	libthr libraries from different	versions of FreeBSD is
       not supported.  The run-time linker ld-elf.so.1(1) has some code	to en-
       sure backward-compatibility with	older versions of libthr.

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

MUTEX ACQUISITION
       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
       PTHREAD_MUTEX_ADAPTIVE_NP  type	and  PTHREAD_PRIO_NONE	protocol  (see
       pthread_mutexattr(3)).

       First,  on SMP systems, a spin loop is performed, where the library at-
       tempts to acquire the lock by atomic(9) operations.  The	loop count  is
       controlled by the LIBPTHREAD_SPINLOOPS environment variable, with a de-
       fault 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	owner-
       ship of the lock	to the woken thread when the lock becomes available.

THREAD STACKS
       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
       kernel, and is controlled by the	RLIMIT_STACK  process  resource	 limit
       (see getrlimit(2)).

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

       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)	 func-
       tions.  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.

RUN-TIME SETTINGS
       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.

       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
				      acquisition.  The	value is the count  of
				      loop operations.

       LIBPTHREAD_QUEUE_FIFO	      The integer value	of the variable	speci-
				      fies  how	 often blocked threads are in-
				      serted at	the head of the	 sleep	queue,
				      instead  of its tail.  Bigger values re-
				      duce the frequency of  the  FIFO	disci-
				      pline.   The value must be between 0 and
				      255.

       LIBPTHREAD_UMTX_MIN_TIMEOUT    The minimal amount of time, in  nanosec-
				      onds,  the  thread  is required to sleep
				      for  pthread  operations	specifying   a
				      timeout.	 If  the  operation requests a
				      timeout less than	the value provided, it
				      is silently increased to the value.  The
				      value of	zero  means  no	 minimum  (de-
				      fault).

       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  au-
					    tomatically	 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  Vir-
					    tual  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 sounds.

       kern.ipc.umtx_max_robust		    The	 maximal  number of robust mu-
					    texes allowed for one thread.  The
					    kernel will	not  unlock  more  mu-
					    texes    than    specified,	   see
					    _umtx_op(2)	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 in-
					    consistency, as a measure to  pre-
					    vent memory	corruption.

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

INTERACTION WITH RUN-TIME LINKER
       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 sup-
       port 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.

SIGNALS
       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.

       The  libthr  library uses the SIGTHR signal for internal	operations, in
       particular, for cancellation requests.  This signal's masking and  dis-
       position	is controlled by the library, and user programs	should not try
       to  modify  them.  The library interposes functions controlling signals
       to prevent inadvertent modifications and	to guard portable code against
       exposure	to SIGTHR.

       Note: similarly,	the SIGLIBRT signal is reserved	for use	by POSIX Real-
       time Library (librt, -lrt), and should be not modified by users.

PROCESS-SHARED SYNCHRONIZATION OBJECTS
       In the libthr implementation, user-visible types	for  all  synchroniza-
       tion  objects  (e.g.  pthread_mutex_t)  are pointers to internal	struc-
       tures, allocated	either by the  corresponding  pthread_<objtype>_init()
       method  call,  or implicitly on first use when a	static initializer was
       specified.  The initial implementation of process-private  locking  ob-
       ject  used  this	 model	with  internal allocation, and the addition of
       process-shared objects was done in a way	that did not break the	appli-
       cation binary interface.

       For  process-private objects, the internal structure is allocated using
       either malloc(3)	or, for	pthread_mutex_init(3), an internal memory  al-
       locator	implemented  in	libthr.	 The internal allocator	for mutexes is
       used to avoid bootstrap	issues	with  many  malloc(3)  implementations
       which need working mutexes to function.	The same allocator is used for
       thread-specific data, see pthread_setspecific(3), for the same reason.

       For  process-shared objects, the	internal structure is created by first
       allocating  a  shared  memory  segment  using   _umtx_op(2)   operation
       UMTX_OP_SHM,  and  then	mapping	 it  into  process  address space with
       mmap(2) with the	MAP_SHARED flag.  The POSIX standard requires that:

       only the	process-shared synchronization object itself can be used for
       performing synchronization.  It need not	be referenced at the address
       used to initialize it (that is, another mapping of the same object can
       be used).

       With the	FreeBSD	implementation,	process-shared	objects	 require  ini-
       tialization  in	each process that use them.  In	particular, if you map
       the shared memory containing the	user portion of	a  process-shared  ob-
       ject already initialized	in different process, locking functions	do not
       work on it.

       Another	broken	case  is  a forked child creating the object in	memory
       shared with the parent, which cannot be used from  parent.   Note  that
       processes  should not use non-async-signal safe functions after fork(2)
       anyway.

SEE ALSO
       ktrace(1),   ld-elf.so.1(1),   _umtx_op(2),   errno(2),	 getrlimit(2),
       thr_exit(2),   thr_kill(2),   thr_kill2(2),   thr_new(2),  thr_self(2),
       thr_set_name(2),	 dlclose(3),  dlopen(3),  getenv(3),  pthread_attr(3),
       pthread_attr_setstacksize(3), pthread_create(3),	signal(3), atomic(9)

HISTORY
       The libthr library first	appeared in FreeBSD 5.2.

AUTHORS
       The   libthr   library	was   originally   created  by	Jeff  Roberson
       <jeff@FreeBSD.org>, and enhanced	by  Jonathan  Mini  <mini@FreeBSD.org>
       and Mike	Makonnen <mtm@FreeBSD.org>.  It	has been substantially rewrit-
       ten and optimized by David Xu <davidxu@FreeBSD.org>.

FreeBSD	ports 15.1		October	1, 2021			     LIBTHR(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=libthr&sektion=3&manpath=FreeBSD+15.1-RELEASE+and+Ports>

home | help