Commit Graph

952 Commits

Author SHA1 Message Date
msaitoh 984bb2b315 s/reseting/resetting/ 2020-07-22 01:24:39 +00:00
ad 7a60fa0a18 Another bug. The CAS loop in pthread_cond_signal() could race against the
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.
2020-06-14 21:33:28 +00:00
ad 6088a8599a Don't need to ignore ESRCH from _lwp_park() any more. 2020-06-14 21:31:11 +00:00
riastradh 025a8ce8b7 Nix trailing whitespace. 2020-06-13 17:39:42 +00:00
ad 30140ed218 Drop self->pt_lock before clearing TSD / malloc TSD. 2020-06-11 18:42:02 +00:00
ad 2b4d53924f Adjust memory barriers. 2020-06-11 18:41:22 +00:00
ad 62e0939e7d - Make pthread_condvar and pthread_mutex work on the stack rather than in
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.
2020-06-10 22:45:15 +00:00
ad b81fe3a293 Adjust previous. In the condvar case the wakeup might already have been
eaten.
2020-06-06 22:23:59 +00:00
riastradh 0b4833402a Nix trailing whitespace. NFCI. 2020-06-04 04:40:01 +00:00
joerg 558a0c7357 If _malloc_thread_cleanup is implement, call it from libpthread.
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.
2020-06-04 00:45:32 +00:00
ad 051faad4aa Deal with a couple of problems with threads being awoken early due to
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.
2020-06-03 22:10:24 +00:00
joerg 34a4ae727b Pass down errno when calling pthread__errorfunc after a system call.
Allow format arguments for that reason and use (v)snprintf_ss in
pthread_errorfunc to avoid race conditions and the like.
2020-06-02 00:29:53 +00:00
ad 06d492d198 In the interests of reliability simplify waiter handling more and redo
condvars to manage the list of waiters with atomic ops.
2020-06-01 11:44:59 +00:00
ad bc77394ce5 - Try to eliminate a hang in "parked" I've been seeing while stress testing.
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.
2020-05-16 22:53:37 +00:00
joerg 858ee362bb Lock/unlock/reinit pthread__deadqueue_lock over fork. 2020-05-15 14:30:23 +00:00
joerg 1116ee1756 Improve TSD behavior
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.
2020-04-19 20:47:03 +00:00
joerg 57360565c8 Reinit TSD mutex in the child to avoid issues with former waiters 2020-04-19 20:46:04 +00:00
joerg f3cc99aec6 Drop most of the logic associated with pthread__started.
The pthread_cond logic is a questionable optimisation at best and the
post-fork logic is plainly broken.
2020-04-14 23:35:07 +00:00
rin 92a204309a Revert previous:
http://mail-index.netbsd.org/source-changes/2020/02/20/msg114173.html

Comment turned out to be wrong, and KASSERT fires for oea.

XXX
Need to revisit shortly...
2020-04-11 09:15:23 +00:00
rin e3331ab957 libpthread sets initial value of MSR for lwp's. However, appropriate
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()
2020-02-20 07:07:02 +00:00
kamil 331480e6b2 Revert "Enhance the pthread(3) + malloc(3) init model"
It is reported to hand on aarch64 with gzip.
2020-02-16 17:45:11 +00:00
kamil bcfb2645e2 Set __isthreaded before bootstrapping malloc(3)
jemalloc depends on the __isthreaded dynamic state logic.

Reported by <wiz> for mpv and by <tih> for gzip.
2020-02-16 17:14:31 +00:00
kamil 5fa609827b Enhance the pthread(3) + malloc(3) init model
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.
2020-02-15 23:59:30 +00:00
kamil f66ccdf057 Change the behavior of pthread_equal()
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.
2020-02-08 17:06:03 +00:00
ryoon 2da2192d78 Remove trailing whiteapaces and tab 2020-02-05 14:56:04 +00:00
kamil 91719d9fbd Retire ifdef ERRORCHECK in pthread(3)
It is enabled unconditionally since 2003 and used only for rwlocks and
spinlocks.

LLVM sanitizers make assumptions that these checks are enabled always.
2020-02-05 11:05:10 +00:00
kamil 31ebab1943 Revert previous
'git grep' breaks now.
2020-02-01 18:14:16 +00:00
kamil f93ad70739 Remove 'ifdef 0' hacks
It is no longer needed as the proper fix avoiding premature malloc()
landed the sources.
2020-02-01 15:39:56 +00:00
kamil 260b3a1721 Refactor libpthread checks for invalid arguments
Switch from manual functions to pthread__error().
2020-01-31 17:52:14 +00:00
christos bbb79fe856 In the same spirit as the previous pthread_mutex_init change for jemalloc,
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.
2020-01-31 02:37:46 +00:00
kamil 12ee584ac8 Use pthread_mutexattr_t and pthread_mutex_t magic fields
Validate _PT_MUTEX_MAGIC in pthread_mutex_t and _PT_MUTEXATTR_MAGIC
in pthread_mutexattr_t accordingly.
2020-01-29 21:11:24 +00:00
ad fb0af629d1 - pthread_join(): remove temporary hack now kernel returns correct errno.
- kill(getpid(), SIGABRT)  ->  _lwp_kill(_lwp_self(), SIGABRT)
2020-01-29 17:11:57 +00:00
kamil 08c17fb31c Check thread->pt_magic with PT_MAGIC promptly 2020-01-29 16:34:09 +00:00
kamil 20668e1417 Chack thread->pt_magic with PT_MAGIC promptly
Rearrange some checks to avoid verifying pthread_t after using it.
2020-01-29 16:03:44 +00:00
kamil ac02e87024 Revert previous
Two assignments are correct.
2020-01-29 15:31:14 +00:00
kamil 0b0b4cd405 Do not set stackbase2 twice for !__MACHINE_STACK_GROWS_UP 2020-01-29 15:15:00 +00:00
kamil e06a99c91d Use pthread_condattr_t and pthread_cond_t magic fields
Validate _PT_CONDATTR_MAGIC and _PT_COND_MAGIC respectively.
2020-01-29 15:07:46 +00:00
kamil 7f6f4173b3 Use pthread_barrierattr_t and pthread_barrier_t magic fields
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.
2020-01-29 14:41:57 +00:00
kamil b3401c13c3 Use the pta_magic field in pthread attribute
Set PT_ATTR_DEAD on pthread_attr_destroy().
Check pta_magic before using pthread_attr_t in a bunch of other functions.
2020-01-29 13:47:31 +00:00
kamil d48cac510b Mark destroyed pthread_mutexattr_t as dead 2020-01-29 10:55:23 +00:00
ad c6559e920a - A bit more alignment in __pthread_st especially for the rbtree node.
- Use COHERENCY_UNIT from sys/param.h.
2020-01-28 13:08:40 +00:00
ad a15e545ef6 pthread_join(): add a temporary hack to make lib/libpthread/t_detach pass.
The correct fix is to do this in kernel (I have that change, but it's part
of the wider change to index LWPs in a tree).
2020-01-28 09:23:15 +00:00
ad cd1754ab41 pthread_detach(), pthread_join(): go back to using _lwp_detach() and
_lwp_wait(), rather than doing it all in userspace.  There's less to go
wrong.  Doesn't seem to be a performance penalty.
2020-01-27 20:50:05 +00:00
ad e354694931 Adjustment to previous: don't call _lwp_unpark_all() with nwaiters == 0. 2020-01-25 18:30:41 +00:00
ad 047ca71b68 pthread_exit(): it looks there there is at least one path through which
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
2020-01-25 18:01:28 +00:00
ad 769155beb0 pthread__mutex_unlock_slow(): ignore the DEFERRED bit. It's only purpose
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
2020-01-25 17:58:28 +00:00
ad edf01486dd - Fix a race between the kernel and libpthread, where a new thread can start
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.
2020-01-25 15:41:52 +00:00
ad 510021886a Rip out some very ambitious optimisations around pthread_mutex that are
don't buy much.  This stuff is hard enough to get right in the kernel let
alone userspace, and I don't trust that it's right.
2020-01-13 18:22:56 +00:00
msaitoh ba5c90c4a4 s/sucess/success/ in comment. 2019-12-27 09:45:26 +00:00
joerg 8e5b2c30bd Since pthread_setspecific requires locks, ensure that they are acquired
before fork and dropped in both parent and child. At least Python
depends on TSD after fork, even though it is undefined behavior in
POSIX.
2019-12-25 00:44:45 +00:00