History log of /freebsd-current/lib/libthr/thread/thr_cond.c
Revision Date Author Comments
# 8f86c108 12-Mar-2024 Brooks Davis <brooks@FreeBSD.org>

libthr: restore _pthread_cond_timedwait

The function was renamed to _thr_cond_timedwait in commit 0ab1bfc7b28f
and for some reason did not get the same __weak_reference treatment as
other _pthread_cond symbols.

Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D44244


# f8bbbce4 06-Mar-2024 Konstantin Belousov <kib@FreeBSD.org>

libthr: remove explicit sys/cdefs.h includes

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 1d386b48 16-Aug-2023 Warner Losh <imp@FreeBSD.org>

Remove $FreeBSD$: one-line .c pattern

Remove /^[\s*]*__FBSDID\("\$FreeBSD\$"\);?\s*\n/


# 4d846d26 10-May-2023 Warner Losh <imp@FreeBSD.org>

spdx: The BSD-2-Clause-FreeBSD identifier is obsolete, drop -FreeBSD

The SPDX folks have obsoleted the BSD-2-Clause-FreeBSD identifier. Catch
up to that fact and revert to their recommended match of BSD-2-Clause.

Discussed with: pfg
MFC After: 3 days
Sponsored by: Netflix


# c7904405 07-Apr-2022 Andrew Turner <andrew@FreeBSD.org>

Remove PAGE_SIZE from libthr

In libthr we use PAGE_SIZE when allocating memory with mmap and to check
various structs will fit into a single page so we can use this allocator
for them.

Ask the kernel for the page size on init for use by the page allcator
and add a new machine dependent macro to hold the smallest page size
the architecture supports to check the structure is small enough.

This allows us to use the same libthr on arm64 with either 4k or 16k
pages.

Reviewed by: kib, markj, imp
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D34984


# 0ab1bfc7 31-Jul-2019 Konstantin Belousov <kib@FreeBSD.org>

Avoid conflicts with libc symbols in libthr jump table.

In some corner cases of static linking and unexpected libraries order
on the linker command line, libc symbol might preempt the same libthr
symbol, in which case libthr jump table points back to libc causing
either infinite recursion or loop. Handle all of such symbols by
using private libthr names for them, ensuring that the right pointers
are installed into the table.

In collaboration with: arichardson
PR: 239475
Tested by: pho
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D21088


# b16150ea 08-Mar-2019 Mark Johnston <markj@FreeBSD.org>

Have pthread_cond_destroy() return EBUSY if the condvar has waiters.

This is not required of a compliant implementation, but it's easy to
check for and helps improve compatibility with other common
implementations. Moreover, it's consistent with our
pthread_mutex_destroy().

PR: 234805
Reviewed by: jhb, kib, ngie
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D19496


# b6413b6d 17-Aug-2018 Pedro F. Giffuni <pfg@FreeBSD.org>

POSIX compliance improvements in the pthread(3) functions.

This basically adds makes use of the C99 restrict keyword, and also
adds some 'const's to four threading functions: pthread_mutexattr_gettype(),
pthread_mutexattr_getprioceiling(), pthread_mutexattr_getprotocol(), and
pthread_mutex_getprioceiling. The changes are in accordance to POSIX/SUSv4-2018.

Hinted by: DragonFlyBSD

Relnotes: yes
MFC after: 1 month
Differential Revision: D16722


# 5e53a4f9 25-Nov-2017 Pedro F. Giffuni <pfg@FreeBSD.org>

lib: further adoption of SPDX licensing ID tags.

Mainly focus on files that use BSD 2-Clause license, however the tool I
was using mis-identified many licenses so this was mostly a manual - error
prone - task.

The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.


# 4dafad49 06-Dec-2016 Konstantin Belousov <kib@FreeBSD.org>

Do not leak curthread->inact_mtx when cancelling in pthread_cond_wait(3).

Leave robust-protected region before checking for cancellation by
calling _thr_testcancel(). Otherwise, if cancelling request was
pending, the cancel handler is called with the dandling inact_mtx,
which triggers an assert if any mutex operation is performed by the
handler.

Reported and tested by: Dimitri Staessens <dimitri.staessens@intec.ugent.be>
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# c72ef5ea 01-Jun-2016 Conrad Meyer <cem@FreeBSD.org>

libthr: Use formatted PANIC()

No functional change, although _thread_printf() may be slightly less functional
or render some values differently from libc snprintf(3). No ABI change.

Reviewed by: kib
Sponsored by: EMC / Isilon Storage Division
Differential Revision: https://reviews.freebsd.org/D6672


# 6180f50b 29-May-2016 Konstantin Belousov <kib@FreeBSD.org>

Stop inlining the struct ucond definition into struct pthread_cond.
This avoids unneccessary casts and make the calls to _thr_ucond_*()
functions less questionable.

The c_spare field was not included into struct pthread_cond, so the
change modifies libthr ABI for shared condvars. But since an off-page
does not legitimately contains any other data past the struct
pthread_cond, the change keeps shared condvars from pre- and post-
changed libthr compatible. Also note that the whole struct ucond was
never copied in or out by kernel.

For private condvars, the privately allocated memory was never exposed
outside libthr.

Sponsored by: The FreeBSD Foundation


# 2a339d9e 17-May-2016 Konstantin Belousov <kib@FreeBSD.org>

Add implementation of robust mutexes, hopefully close enough to the
intention of the POSIX IEEE Std 1003.1TM-2008/Cor 1-2013.

A robust mutex is guaranteed to be cleared by the system upon either
thread or process owner termination while the mutex is held. The next
mutex locker is then notified about inconsistent mutex state and can
execute (or abandon) corrective actions.

The patch mostly consists of small changes here and there, adding
neccessary checks for the inconsistent and abandoned conditions into
existing paths. Additionally, the thread exit handler was extended to
iterate over the userspace-maintained list of owned robust mutexes,
unlocking and marking as terminated each of them.

The list of owned robust mutexes cannot be maintained atomically
synchronous with the mutex lock state (it is possible in kernel, but
is too expensive). Instead, for the duration of lock or unlock
operation, the current mutex is remembered in a special slot that is
also checked by the kernel at thread termination.

Kernel must be aware about the per-thread location of the heads of
robust mutex lists and the current active mutex slot. When a thread
touches a robust mutex for the first time, a new umtx op syscall is
issued which informs about location of lists heads.

The umtx sleep queues for PP and PI mutexes are split between
non-robust and robust.

Somewhat unrelated changes in the patch:
1. Style.
2. The fix for proper tdfind() call use in umtxq_sleep_pi() for shared
pi mutexes.
3. Removal of the userspace struct pthread_mutex m_owner field.
4. The sysctl kern.ipc.umtx_vnode_persistent is added, which controls
the lifetime of the shared mutex associated with a vnode' page.

Reviewed by: jilles (previous version, supposedly the objection was fixed)
Discussed with: brooks, Martin Simmons <martin@lispworks.com> (some aspects)
Tested by: pho
Sponsored by: The FreeBSD Foundation


# 32793011 08-Apr-2016 Konstantin Belousov <kib@FreeBSD.org>

Use __FBSDID() for .c files from lib/libthr/thread.

Sponsored by: The FreeBSD Foundation


# 9e821f27 08-Apr-2016 Konstantin Belousov <kib@FreeBSD.org>

Assert that the lock objects put into the off-page, fit into the page.

Sponsored by: The FreeBSD Foundation


# 1bdbd705 28-Feb-2016 Konstantin Belousov <kib@FreeBSD.org>

Implement process-shared locks support for libthr.so.3, without
breaking the ABI. Special value is stored in the lock pointer to
indicate shared lock, and offline page in the shared memory is
allocated to store the actual lock.

Reviewed by: vangyzen (previous version)
Discussed with: deischen, emaste, jhb, rwatson,
Martin Simmons <martin@lispworks.com>
Tested by: pho
Sponsored by: The FreeBSD Foundation


# 585bf8ae 02-Sep-2014 Rui Paulo <rpaulo@FreeBSD.org>

Fix typo in a comment.


# aa75bc57 11-Aug-2012 David Xu <davidxu@FreeBSD.org>

Do defered mutex wakeup once.


# e220a13a 11-Aug-2012 David Xu <davidxu@FreeBSD.org>

MFp4:
Further decreases unexpected context switches by defering mutex wakeup
until internal sleep queue lock is released.


# 1f6f22df 03-Jan-2011 David Xu <davidxu@FreeBSD.org>

Because sleepqueue may still being used, we should always check wchan with
queue locked.


# d1078b0b 21-Dec-2010 David Xu <davidxu@FreeBSD.org>

MFp4:

- Add flags CVWAIT_ABSTIME and CVWAIT_CLOCKID for umtx kernel based
condition variable, this should eliminate an extra system call to get
current time.

- Add sub-function UMTX_OP_NWAKE_PRIVATE to wake up N channels in single
system call. Create userland sleep queue for condition variable, in most
cases, thread will wait in the queue, the pthread_cond_signal will defer
thread wakeup until the mutex is unlocked, it tries to avoid an extra
system call and a extra context switch in time window of pthread_cond_signal
and pthread_mutex_unlock.

The changes are part of process-shared mutex project.


# a7d5f7eb 19-Oct-2010 Jamie Gritton <jamie@FreeBSD.org>

A new jail(8) with a configuration file, to replace the work currently done
by /etc/rc.d/jail.


# bbb64c21 27-Sep-2010 David Xu <davidxu@FreeBSD.org>

In current code, statically initialized and destroyed object have
same null value, the code can not distinguish between them, to
fix the problem, now a destroyed object is assigned to a non-null
value, and it will be rejected by some pthread functions.
PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP is changed to number 1, so that
adaptive mutex can be statically initialized correctly.


# 02c3c858 31-Aug-2010 David Xu <davidxu@FreeBSD.org>

Add signal handler wrapper, the reason to add it becauses there are
some cases we want to improve:
1) if a thread signal got a signal while in cancellation point,
it is possible the TDP_WAKEUP may be eaten by signal handler
if the handler called some interruptibly system calls.
2) In signal handler, we want to disable cancellation.
3) When thread holding some low level locks, it is better to
disable signal, those code need not to worry reentrancy,
sigprocmask system call is avoided because it is a bit expensive.
The signal handler wrapper works in this way:
1) libthr installs its signal handler if user code invokes sigaction
to install its handler, the user handler is recorded in internal
array.
2) when a signal is delivered, libthr's signal handler is invoke,
libthr checks if thread holds some low level lock or is in critical
region, if it is true, the signal is buffered, and all signals are
masked, once the thread leaves critical region, correct signal
mask is restored and buffered signal is processed.
3) before user signal handler is invoked, cancellation is temporarily
disabled, after user signal handler is returned, cancellation state
is restored, and pending cancellation is rescheduled.


# 635f917a 19-Aug-2010 David Xu <davidxu@FreeBSD.org>

In current implementation, thread cancellation is done in signal handler,
which does not know what is the state of interrupted system call, for
example, open() system call opened a file and the thread is still cancelled,
result is descriptor leak, there are other problems which can cause resource
leak or undeterminable side effect when a thread is cancelled. However, this
is no longer true in new implementation.

In defering mode, a thread is canceled if cancellation request is pending and
later the thread enters a cancellation point, otherwise, a later
pthread_cancel() just causes SIGCANCEL to be sent to the target thread, and
causes target thread to abort system call, userland code in libthr then checks
cancellation state, and cancels the thread if needed. For example, the
cancellation point open(), the thread may be canceled at start,
but later, if it opened a file descriptor, it is not canceled, this avoids
file handle leak. Another example is read(), a thread may be canceled at start
of the function, but later, if it read some bytes from a socket, the thread
is not canceled, the caller then can decide if it should still enable cancelling
or disable it and continue reading data until it thinks it has read all
bytes of a packet, and keeps a protocol stream in health state, if user ignores
partly reading of a packet without disabling cancellation, then second iteration
of read loop cause the thread to be cancelled.
An exception is that the close() cancellation point always closes a file handle
despite whether the thread is cancelled or not.

The old mechanism is still kept, for a functions which is not so easily to
fix a cancellation problem, the rough mechanism is used.

Reviewed by: kib@


# fe0506d7 09-Mar-2010 Marcel Moolenaar <marcel@FreeBSD.org>

Create the altix project branch. The altix project will add support
for the SGI Altix 350 to FreeBSD/ia64. The hardware used for porting
is a two-module system, consisting of a base compute module and a
CPU expansion module. SGI's NUMAFlex architecture can be an excellent
platform to test CPU affinity and NUMA-aware features in FreeBSD.


# d7f03759 19-Oct-2008 Ulf Lilleengen <lulf@FreeBSD.org>

- Import the HEAD csup code which is the basis for the cvsmode work.


# 8b873a23 02-Apr-2008 David Xu <davidxu@FreeBSD.org>

Remove unused functions.


# 5ab512bb 30-Mar-2008 David Xu <davidxu@FreeBSD.org>

Rewrite rwlock to user atomic operations to change rwlock state, this
eliminates internal mutex lock contention when most rwlock operations
are read.

Orignal patch provided by: jeff


# 347126a2 11-Dec-2006 David Xu <davidxu@FreeBSD.org>

Move checking for c_has_waiters into low level _thr_ucond_signal and
_thr_ucond_broadcast, clear condition variable pointer in cancellation
info after returing from _thr_ucond_wait, since kernel has already
dropped the internal lock, so we don't need to unlock it in cancellation
handler again.


# 3b8a0174 05-Dec-2006 David Xu <davidxu@FreeBSD.org>

the c_has_waiters is lazily updated, temporarily disable the false
alarm code.


# 2bd2c907 04-Dec-2006 David Xu <davidxu@FreeBSD.org>

Use kernel provided userspace condition variable to implement pthread
condition variable.


# f08e1bf6 24-Nov-2006 David Xu <davidxu@FreeBSD.org>

Eliminate atomic operations in thread cancellation functions, it should
reduce overheads of cancellation points.


# bddd24cd 05-Sep-2006 David Xu <davidxu@FreeBSD.org>

Replace internal usage of struct umtx with umutex which can supports
real-time if we want, no functionality is changed.


# a9794459 08-Apr-2006 David Xu <davidxu@FreeBSD.org>

Do not check validity of timeout if a mutex can be acquired immediately.
Completly drop recursive mutex in pthread_cond_wait and restore recursive
after resumption. Reorganize code to make gcc to generate better code.


# 37a6356b 03-Apr-2006 David Xu <davidxu@FreeBSD.org>

WARNS level 4 cleanup.


# a091d823 01-Apr-2005 David Xu <davidxu@FreeBSD.org>

Import my recent 1:1 threading working. some features improved includes:
1. fast simple type mutex.
2. __thread tls works.
3. asynchronous cancellation works ( using signal ).
4. thread synchronization is fully based on umtx, mainly, condition
variable and other synchronization objects were rewritten by using
umtx directly. those objects can be shared between processes via
shared memory, it has to change ABI which does not happen yet.
5. default stack size is increased to 1M on 32 bits platform, 2M for
64 bits platform.
As the result, some mysql super-smack benchmarks show performance is
improved massivly.

Okayed by: jeff, mtm, rwatson, scottl


# cd28f17d 01-Jul-2004 Marcel Moolenaar <marcel@FreeBSD.org>

Change the thread ID (thr_id_t) used for 1:1 threading from being a
pointer to the corresponding struct thread to the thread ID (lwpid_t)
assigned to that thread. The primary reason for this change is that
libthr now internally uses the same ID as the debugger and the kernel
when referencing to a kernel thread. This allows us to implement the
support for debugging without additional translations and/or mappings.

To preserve the ABI, the 1:1 threading syscalls, including the umtx
locking API have not been changed to work on a lwpid_t. Instead the
1:1 threading syscalls operate on long and the umtx locking API has
not been changed except for the contested bit. Previously this was
the least significant bit. Now it's the most significant bit. Since
the contested bit should not be tested by userland, this change is
not expected to be visible. Just to be sure, UMTX_CONTESTED has been
removed from <sys/umtx.h>.

Reviewed by: mtm@
ABI preservation tested on: i386, ia64


# 4cd18a22 19-May-2004 Mike Makonnen <mtm@FreeBSD.org>

Make libthr async-signal-safe without costly signal masking. The guidlines I
followed are: Only 3 functions (pthread_cancel, pthread_setcancelstate,
pthread_setcanceltype) are required to be async-signal-safe by POSIX. None of
the rest of the pthread api is required to be async-signal-safe. This means
that only the three mentioned functions are safe to use from inside
signal handlers.
However, there are certain system/libc calls that are
cancellation points that a caller may call from within a signal handler,
and since they are cancellation points calls have to be made into libthr
to test for cancellation and exit the thread if necessary. So, the
cancellation test and thread exit code paths must be async-signal-safe
as well. A summary of the changes follows:

o Almost all of the code paths that masked signals, as well as locking the
pthread structure now lock only the pthread structure.
o Signals are masked (and left that way) as soon as a thread enters
pthread_exit().
o The active and dead threads locks now explicitly require that signals
are masked.
o Access to the isdead field of the pthread structure is protected by both
the active and dead list locks for writing. Either one is sufficient for
reading.
o The thread state and type fields have been combined into one three-state
switch to make it easier to read without requiring a lock. It doesn't need
a lock for writing (and therefore for reading either) because only the
current thread can write to it and it is an integer value.
o The thread state field of the pthread structure has been eliminated. It
was an unnecessary field that mostly duplicated the flags field, but
required additional locking that would make a lot more code paths require
signal masking. Any truly unique values (such as PS_DEAD) have been
reborn as separate members of the pthread structure.
o Since the mutex and condvar pthread functions are not async-signal-safe
there is no need to muck about with the wait queues when handling
a signal ...
o ... which also removes the need for wrapping signal handlers and sigaction(2).
o The condvar and mutex async-cancellation code had to be revised as a result
of some of these changes, which resulted in semi-unrelated changes which
would have been difficult to work on as a separate commit, so they are
included as well.

The only part of the changes I am worried about is related to locking for
the pthread joining fields. But, I will take a closer look at them once this
mega-patch is committed.


# 61bf8f47 29-Mar-2004 Mike Makonnen <mtm@FreeBSD.org>

If a condition variable is statically initialized don't return
an error. Return successfully without doing anything.


# 0c3a9426 29-Mar-2004 Mike Makonnen <mtm@FreeBSD.org>

The thread suspend function now returns ETIMEDOUT, not EAGAIN.


# 7c8aa413 27-Mar-2004 Mike Makonnen <mtm@FreeBSD.org>

Stop using signals for synchronizing threads. The performance penalty
was too much.


# 89552201 09-Dec-2003 Mike Makonnen <mtm@FreeBSD.org>

Fix the wrapper function around signals so that a signal handling
thread on one of the mutex or condition variable queues is removed
from those queues before the real signal handler is called.


# fadd82e3 29-Jun-2003 Mike Makonnen <mtm@FreeBSD.org>

Catchup with _thread_suspend() changes.


# 6e1aa51e 31-May-2003 Mike Makonnen <mtm@FreeBSD.org>

I botched one of my committs in the last round. Fix it.


# 41f2bd85 29-May-2003 Mike Makonnen <mtm@FreeBSD.org>

Use a static lock to ake sure pthread_cond_* functions called
from multiple threads don't initialze the same condition variable
more than once.

Explicitly compare cond pointers with PTHREAD_COND_INITIALIZER instead
of NULL. Just because it happens to be defined as NULL is no reason
to encourage the idea that people can call those functions with
NULL pointers to a condition variable.

Approved by: re/jhb


# a224a391 23-May-2003 Mike Makonnen <mtm@FreeBSD.org>

Lock the cond queue (condition variables):
Access to the thread's flags and state is protected by
_thread_critical_enter/exit(). When a thread is signaled with a condition
its state must be protected by locking it and disabling
signals before it is taken of the waiters' queue.

Move the implementation of pthread_cond_signal() and pthread_cond_broadcast()
into one function, cond_signal(). Its behaviour is determined by the
last argument, int broadcast. If this is set to 1 it will remove all
waiters, otherwise it will wake up only the first waiter thread.

Remove an extraneous call to pthread_testcancel().

Approved by: re/blanket libthr


# 6439d4c2 20-May-2003 Mike Makonnen <mtm@FreeBSD.org>

Insert a debugging aid:
When in either the mutex or cond queue we notice that the thread
is already on one of the queues, don't just simply abort(). Print
out the thread's identifiers and what queue it was on.

Approved by: markm/mentor, re/blanket libthr


# dd3b229e 15-May-2003 Mike Makonnen <mtm@FreeBSD.org>

Do some cleanup with respect to condition variables. The implementation
of pthread_cond_timedwait() is moved into cond_wait_common().
Pthread_cond_wait() and pthread_cond_timedwait() are now wrappers around
this function. Previously, the former called the latter with the abstime
pointing to 0 time. This violated Posix semantics should an application
have reason to call it with that argument because instead or returning
immediately it would have waited indefinitely for the cv to be signaled.

Approved by: markm/mentor, re/blanket libthr
Reviewed by: jeff


# 26f52e2f 01-Apr-2003 Jeff Roberson <jeff@FreeBSD.org>

- Define curthread as _get_curthread() and remove all direct calls to
_get_curthread(). This is similar to the kernel's curthread. Doing
this saves stack overhead and is more convenient to the programmer.
- Pass the pointer to the newly created thread to _thread_init().
- Remove _get_curthread_slow().


# 00c30154 01-Apr-2003 Jeff Roberson <jeff@FreeBSD.org>

- Don't drop and reacquire giant in thread_suspend(). Change callers to do
this manually. This will facilitate the unrolling of giant.
- Don't allow giant to recurse anymore. This should never happen.


# bb535300 31-Mar-2003 Jeff Roberson <jeff@FreeBSD.org>

- Add libthr but don't hook it up to the regular build yet. This is an
adaptation of libc_r for the thr system call interface. This is beta
quality code.