thread it is trying to awake. The thread could exit the condvar and then
reinsert itself at the head of the list with a new waiter behind it. It's
likely possible to fix this in a way that's wait-free but for now just fix
the bug.
pthread_t, so there's less chance of bad things happening if someone calls
(for example) pthread_cond_broadcast() from a signal handler.
- Remove all the deferred waiter handling except for the one case that really
matters which is transferring waiters from condvar -> mutex on wakeup, and
do that by splicing the condvar's waiters onto the mutex.
- Remove the mutex waiters bit as it's another complication that's not
strictly needed.
Provide the hook from modern jemalloc to avoid using TSD for the thread
destruction cleanup as it can result in reentrancy crashes if fork is
called from a thread that never called malloc as it will result in a
late malloc from the pre-fork synchronisation handler.
timeouts or cancellation where:
- The restarting thread calls _lwp_exit() before another thread gets around
to waking it with _lwp_unpark(), leading to ESRCH (observed by joerg@).
(I may have removed a similar check mistakenly over the weekend.)
- The restarting thread considers itself gone off the sleep queue but
at the same time another thread is part way through waking it, and hasn't
fully completed that operation yet by setting thread->pt_mutexwait = 0.
I think that could have potentially lead to the list of waiters getting
messed up given the right circumstances.
Centralise wakeup of deferred waiters in pthread__clear_waiters() and use
throughout libpthread. Make fewer assumptions. Be more conservative in
pthread_mutex when dealing with pending waiters.
- Remove the "hint" argument everywhere since the kernel doesn't use it any
more.
Optimistically check whether the key has been used by this thread
already and avoid locking in that case. This avoids the atomic operation
in the hot path. When the value is set to non-NULL for the first time,
put the entry on the to-be-freed list and keep it their until
destruction or thread exit. Setting the key to NULL and back is common
enough and updating the list is more expensive than the extra check on
the final round.
value differs b/w oea/booke/ibm4xx, and there's no way to obtain it
from userland. Therefore, this initial value should be corrected by
cpu_setmcontext().
- Comment this in libpthread
- Add KASSERT in cpu_mcontext_validate()
Separate the pthread_atfork(3) call from pthread_tsd_init()
and move it into a distinct function.
Call inside pthread__init() late TSD initialization route, just after
"pthread_atfork(NULL, NULL, pthread__fork_callback);".
Document that malloc(3) initialization is now controlled again and called
during the first pthread_atfork(3) call.
Remove #if 0 code from pthread_mutex.c as we no longer initialize malloc
prematurely.
On error when not aborting, do not return EINVAL as it has a side effect
of being interpreted as matching threads. For invalid threads return
unmatched.
Check pthreads for NULL, before accessing pt_magic field. This avoids
faults on comparision with a NULL pointer.
This behavior is in the scope of UB, but should be easier to deal with
buggy software.
It is enabled unconditionally since 2003 and used only for rwlocks and
spinlocks.
LLVM sanitizers make assumptions that these checks are enabled always.
make pthread_mutexattr_init do always a full initialization, so that the
attribute that will be used later when we become threaded is properly
initialized.
Set respectively _PT_BARRIER_DEAD for pthread_barrier_destroy() and
_PT_BARRIERATTR_DEAD for pthread_barrierattr_destroy().
Validate _PT_BARRIER_MAGIC in pthread_barrier_t and _PT_BARRIERATTR_MAGIC
in pthread_barrierattr_t accordingly.
a thread can exit with waiters still hanging off it (cancellation when
waiting on a condvar) so deal with all/any crappy failure like that and
make sure there are never any waiters left before exiting. Maybe of help
for:
PR: bin/50350: rump/rumpkern/t_sp/stress_{long,short} fail on Core 2
is to get the thread to go through the slow path. If there are waiters,
process them there and then. Should not affect well behaved apps. Maybe
of help for:
PR bin/50350: rump/rumpkern/t_sp/stress_{long,short} fail on Core 2 Quad
life without its self->pt_lid being filled in.
- Fix an error path in _lwp_create(). If the new LID can't be copied out,
then get rid of the new LWP (i.e. either succeed or fail, not both).
- Mark l_dopreempt and l_nopreempt volatile in struct lwp.