Commit graph

597 commits

Author SHA1 Message Date
Konstantin Belousov 4edfc1e3bf Revert r302194, there are issues with some applications after changing
the return value, in particular console-kit-daemon.

Reported by:	Ivan Klymenko <fidaj@ukr.net>
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Approved by:	re (gjb)
2016-06-25 20:20:24 +00:00
Konstantin Belousov a068480247 For pthread_mutex_trylock() call on owned error-check or non-portable
adaptive mutex, return EDEADLK as required by POSIX.  The
pthread_mutex_lock() is already compliant.

Tested by:	Guy Yur <guyyur@gmail.com>
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Approved by:	re (gjb)
2016-06-25 11:30:40 +00:00
Conrad Meyer c72ef5eab3 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
2016-06-01 16:12:26 +00:00
Conrad Meyer a3c0056121 libthr: _thread_vprintf: Enhance support for %p, %#x
No functional change.  No ABI change.

Reviewed by:	kib
Sponsored by:	EMC / Isilon Storage Division
Differential Revision:	https://reviews.freebsd.org/D6672
2016-06-01 16:11:09 +00:00
Conrad Meyer 3a7d122f96 libthr: Add vprintf variant of _thread_printf, formatted PANIC()
No ABI change.

Reviewed by:	kib
Sponsored by:	EMC / Isilon Storage Division
Differential Revision:	https://reviews.freebsd.org/D6672
2016-06-01 16:09:56 +00:00
Konstantin Belousov 6180f50bbb 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
2016-05-29 19:35:55 +00:00
Konstantin Belousov 2a339d9e3d 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
2016-05-17 09:56:22 +00:00
Konstantin Belousov 321e2a0090 Do not leak THR_FLAGS_SUSPENDED from the previous suspend/resume
cycle.  The flag currently is cleared by the resumed thread.  If next
suspend request comes before the thread was able to clean the flag, in
which case suspender skip the thread.

Instead, clear the THR_FLAGS_SUSPEND flag in resume_common(), we do
not care how much code was executed in the resumed thread when the
pthread_resume_*np(s) functions returned.

PR:	209233
Reported by:	Lawrence Esswood <le277@cam.ac.uk>
MFC after:	1 week
2016-05-05 10:20:22 +00:00
Konstantin Belousov fe60c14631 If off-page lookup failed, there is no memory to perform
shared_mutex_init() upon.

Sponsored by:	The FreeBSD Foundation
2016-04-12 10:25:44 +00:00
Konstantin Belousov 3279301186 Use __FBSDID() for .c files from lib/libthr/thread.
Sponsored by:	The FreeBSD Foundation
2016-04-08 11:15:26 +00:00
Konstantin Belousov 5c43c9a105 Use ANSI C function definitions, fix spelling in a comment.
Sponsored by:	The FreeBSD Foundation
2016-04-08 10:59:06 +00:00
Konstantin Belousov 9e821f2796 Assert that the lock objects put into the off-page, fit into the page.
Sponsored by:	The FreeBSD Foundation
2016-04-08 10:21:43 +00:00
Konstantin Belousov 841ecd471a Remove unused variable. It was write-only before r297139.
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2016-04-04 06:58:59 +00:00
Konstantin Belousov 6044c03a37 Apparently there are some popular programs around which assume that it
is safe to call pthread_mutex_init() on the same shared mutex several
times.  POSIX claims that the behaviour in this case is undefined.

Make this working by only allowing one caller to initialize the mutex.
Other callers either see already completed initialization and do
nothing, or busy-loop yielding while designated initializer finishes.
Also make the API requirements loose by initializing mutexes on other
pthread_mutex*() calls if they see uninitialized shared mutex.

Only mutexes provide the hack for now, but it could be also
implemented for other process shared primitives from libthr.

Reported and tested by:	"Oleg V. Nauman" <oleg@opentransfer.com>
Sponsored by:	The FreeBSD Foundation
2016-03-22 10:51:42 +00:00
Konstantin Belousov 53fd961f05 Lock pshared_lock shared around fork, to ensure that the COW snapshot
of the pshared hash in child is consistent and can be safely used.

Reported and tested by:	"Oleg V. Nauman" <oleg@opentransfer.com>
Sponsored by:	The FreeBSD Foundation
2016-03-21 06:52:35 +00:00
Konstantin Belousov 07f22a288d Provide more information on failing checks in mutex_assert_is_owned()
and mutex_assert_not_owned().  snprintf() use in this context should
be safe.

Sponsored by:	The FreeBSD Foundation
2016-03-21 06:48:11 +00:00
Konstantin Belousov b6751c3f87 From libthr, remove special and strange code to set up session and
control terminal, activated when running with pid 1.  It is
application duty to handle this, and unsuspecting init replacements
which are linked with libthr would be broken by this.

The pre-resolving of getpid() is restored, just in case.

Reviewed by:	jilles
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2016-03-21 06:46:16 +00:00
Konstantin Belousov 6eced731e8 Implement process-shared spinlocks.
Sponsored by:	The FreeBSD Foundation
2016-03-21 06:40:54 +00:00
Konstantin Belousov 064094126c Add two comments explaining the fine points of the hash
implementation.

Reviewed by:	emaste
Sponsored by:	The FreeBSD Foundation
Differential revision:	https://reviews.freebsd.org/D5490
2016-03-01 15:21:01 +00:00
Konstantin Belousov 1bdbd70599 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
2016-02-28 17:52:33 +00:00
Konstantin Belousov bd43f0691c If libthr.so is dlopened without RTLD_GLOBAL flag, the libthr symbols
do not participate in the global symbols namespace, but rtld locks are
still replaced and functions are interposed.  In particular,
__pthread_map_stacks_exec is resolved to the libc version.  If a
library is loaded later, which requires adjustment of the stack
protection mode, rtld calls into libc __pthread_map_stacks_exec due to
the symbols scope.  The libc version might recurse into binder and
recursively acquire rtld bind lock, causing the hang.

Make libc __pthread_map_stacks_exec() interposed, which synchronizes
rtld locks and version of the stack exec hook when libthr loaded,
regardless of the symbol scope control or symbol resolution order.

The __pthread_map_stacks_exec() symbol is removed from the private
version in libthr since libc symbol now operates correctly in presence
of libthr.

Reported and tested by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2016-02-08 19:24:13 +00:00
Eric van Gyzen 8e402f34b9 libthr: const-ify two variables
Make the default umutex and urwlock initializers const,
because they can be, and as a microoptimization.

MFC after:	5 days
Sponsored by:	Dell Inc.
2016-01-13 22:34:55 +00:00
Konstantin Belousov d6717e1b51 Typo. 2015-12-27 01:14:42 +00:00
Jilles Tjoelker 17981398bd libthr: Don't use both __sys_open() and __sys_openat(). 2015-12-20 16:33:56 +00:00
Konstantin Belousov b684727b07 Style. Use ANSI definition, wrap long lines, no initialization in
declaration for locals.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-09-08 08:48:53 +00:00
Konstantin Belousov 3e7e67c08d In the pthread_once(), if the initializer has already run, then the
calling thread is supposed to see accesses issued by the initializer.
This means that the read of the once_control->state variable should
have an acquire semantic.  Use atomic_thread_fence_acq() when the
value read is ONCE_DONE, instead of straightforward atomic_load_acq(),
to only put a barrier when needed (*).

On the other hand, the updates of the once_control->state with the
intermediate progress state do not need to synchronize with other
state accesses, remove _acq suffix.

Reviewed by:	alc (previous version)
Suggested by:	alc (*)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-09-08 08:41:07 +00:00
Konstantin Belousov 3d40192d3d Pre-resolve symbols required for the deferred signal processing. This
avoids recursion into rtld when leaving libthr critical section for
the deferred signal delivery.

For the same reason, use syscall(2) instead of referencing
__sys_sigreturn(2).  Syscall() is already pre-resolved for fork()
interceptor.

Tested by:	Andre Meiser <ortadur@web.de>
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-08-10 17:02:42 +00:00
Pedro F. Giffuni 850c6f5fd2 cosmetic: whitespaces-tab before EOL
Obtained from:	cpi-llvm project
2015-07-08 16:35:24 +00:00
Konstantin Belousov c5e7289c10 Fix typo in comment.
MFC after:	3 days
2015-06-14 19:19:46 +00:00
Konstantin Belousov 9be6046a47 Some third-party malloc(3) implementations use pthread_setspecific(3)
to handle per-thread information.  Since our pthread_setspecific()
implementation calls calloc(3) to allocate per-thread specific data
storage, things get complicated.

Switch the allocator to use bare mmap(2).  There is some loss of the
allocated page, since e.g. on amd64, PTHREAD_KEYS_MAX * sizeof(struct
pthread_specific_elem) is 3K (it actually spans whole page due to
padding), but I believe it is more acceptable than additional code for
specialized allocator().

The alternatives would either to make the specific data array be part of
the struct thread, or use internal bindings to call the libc malloc,
avoiding interposing.

Also do the style pass over the thr_spec.c, esp. simplify the
conditionals nesting by returning early when an error detected.
Remove trivial comments.

Found by:	yuri@rawbw.com
PR:	200138
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2015-05-15 08:40:17 +00:00
Pedro F. Giffuni 9acf5917d3 _pthread_cleanup_push: fix allocator sizeof operand mismatch
Same fix appears to be in DragonFly's libthread_xu.

Found by:	Clang Static Analyzer
MFC after:	1 week
2015-04-22 16:51:21 +00:00
Konstantin Belousov 0538aafc41 The lseek(2), mmap(2), truncate(2), ftruncate(2), pread(2), and
pwrite(2) syscalls are wrapped to provide compatibility with pre-7.x
kernels which required padding before the off_t parameter.  The
fcntl(2) contains compatibility code to handle kernels before the
struct flock was changed during the 8.x CURRENT development.  The
shims were reasonable to allow easier revert to the older kernel at
that time.

Now, two or three major releases later, shims do not serve any
purpose.  Such old kernels cannot handle current libc, so revert the
compatibility code.

Make padded syscalls support conditional under the COMPAT6 config
option.  For COMPAT32, the syscalls were under COMPAT6 already.

Remove WITHOUT_SYSCALL_COMPAT build option, which only purpose was to
(partially) disable the removed shims.

Reviewed by:	jhb, imp (previous versions)
Discussed with:	peter
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-04-18 21:50:13 +00:00
Konstantin Belousov 3d0045bb2b Make wait6(2), waitid(3) and ppoll(2) cancellation points. The
waitid() function is required to be cancellable by the standard.  The
wait6() and ppoll() follow the other syscalls in their groups.

Reviewed by:	jhb, jilles (previous versions)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-04-18 21:35:41 +00:00
Konstantin Belousov b072e86d09 Make kevent(2) a cancellation point.
Note that to cancel blocked kevent(2) call, changelist must be empty,
since we cannot cancel a call which already made changes to the
process state.  And in reverse, call which only makes changes to the
kqueue state, without waiting for an event, is not cancellable.  This
makes a natural usage model to migrate kqueue loop to support
cancellation, where existing single kevent(2) call must be split into
two: first uncancellable update of kqueue, then cancellable wait for
events.

Note that this is ABI-incompatible change, but it is believed that
there is no cancel-safe code that relies on kevent(2) not being a
cancellation point.  Option to preserve the ABI would be to keep
kevent(2) as is, but add new call with flags to specify cancellation
behaviour, which only value seems to add complications.

Suggested and reviewed by:	jilles
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2015-03-29 19:14:41 +00:00
Jung-uk Kim be070eb896 Fix a typo in comment and explain the reason. 2015-03-09 20:26:42 +00:00
Konstantin Belousov 3e6d2e9b4e Propagate errors from _thr_umutex_unlock2 through mutex_unlock_common.
Errors from _thr_umutex_unlock2 should "never happen" in normal
circumstances.  If they do, however, return them to the application
so it can fail early and loudly.  Hiding the errors will only delay
the inevitable failure, making it harder to find and diagnose.

Submitted by:	Eric van Gyzen <eric_van_gyzen@dell.com>
Obtained from:	Dell Inc.
PR:	198914
MFC after:	1 week
2015-02-25 16:18:26 +00:00
Konstantin Belousov 45468c5356 Properly interpose libc spinlocks, was missed in r276630. In
particular, stdio locking was affected.

Reported and tested by:	"Matthew D. Fuller" <fullermd@over-yonder.net>
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2015-02-14 11:47:40 +00:00
Konstantin Belousov 83d74204c8 Fully initialize allocated memory for the new barrier. The
b_destroying member was left uninitialized, which caused spurious
EBUSY.

PR:	197365
Noted by:	Florent Guiliani <fguiliani@verisign.com>
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-02-06 12:18:38 +00:00
Andrew Turner 20fe2c9465 Merge all the copies of _tcb_ctor and _tcb_dtor.
The amd64, i386, and sparc64 versions were identical, with the one
difference where the former two used inline asm instead of _tcb_get. I
have compared the function before and after replacing the asm with _tcb_get
and found the object files to be identical.

The arm, mips, and powerpc versions were almost identical. The only
difference was the powerpc version used an alignment of 1 where arm and
mips used 16. As this is an increase in alignment is will be safe.

Along with this arm, mips, and powerpc all passed, when initial was true,
the value returned from _tcb_get as the first argument to
_rtld_allocate_tls. This would then return this pointer back to the caller.
We can remove these extra calls by checking if initial is set and setting
the thread control block directly. As this is what the sparc64 code does
we can use it directly.

As after these observations all the architectures can now have identical
code we can merge them into a common file.

Differential Revision:	https://reviews.freebsd.org/D1556
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
2015-01-21 16:41:05 +00:00
Konstantin Belousov 9e8bff64cb Fix bug in r276630. Do not allow pthread_sigmask() to block SIGCANCEL.
Reported and tested by:	royger
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2015-01-21 16:13:37 +00:00
Konstantin Belousov 397d851d66 Reduce the size of the interposing table and amount of
cancellation-handling code in the libthr.  Translate some syscalls
into their more generic counterpart, and remove translated syscalls
from the table.

List of the affected syscalls:
creat, open -> openat
raise -> thr_kill
sleep, usleep -> nanosleep
pause -> sigsuspend
wait, wait3, waitpid -> wait4

Suggested and reviewed by:	jilles (previous version)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-01-11 22:16:31 +00:00
Konstantin Belousov 1a744fefc2 Avoid calling internal libc function through PLT or accessing data
though GOT, by staticizing and hiding.  Add setter for
__error_selector to hide it as well.

Suggested and reviewed by:	jilles
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-01-05 01:06:54 +00:00
Konstantin Belousov 8495e8b1e9 Fix known issues which blow up the process after dlopen("libthr.so")
(or loading a dso linked to libthr.so into process which was not
linked against threading library).

- Remove libthr interposers of the libc functions, including
  __error(). Instead, functions calls are indirected through the
  interposing table, similar to how pthread stubs in libc are already
  done.  Libc by default points either to syscall trampolines or to
  existing libc implementations.  On libthr load, libthr rewrites the
  pointers to the cancellable implementations already in libthr.  The
  interposition table is separate from pthreads stubs indirection
  table to not pull pthreads stubs into static binaries.

- Postpone the malloc(3) internal mutexes initialization until libthr
  is loaded.  This avoids recursion between calloc(3) and static
  pthread_mutex_t initialization.

- Reinstall signal handlers with wrapper on libthr load.  The
  _rtld_is_dlopened(3) is used to avoid useless calls to sigaction(2)
  when libthr is statically referenced from the main binary.

In the process, fix openat(2), swapcontext(2) and setcontext(2)
interposing.  The libc symbols were exported at different versions
than libthr interposers.  Export both libc and libthr versions from
libc now, with default set to the higher version from libthr.

Remove unused and disconnected swapcontext(3) userspace implementation
from libc/gen.

No objections from:	deischen
Tested by:	pho, antoine (exp-run) (previous versions)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2015-01-03 18:38:46 +00:00
Ed Maste 294246bb7d Revert r274772: it is not valid on MIPS
Reported by:	sbruno
2014-11-25 03:50:31 +00:00
Ed Maste 688fd61ae8 Use canonical __PIC__ flag
It is automatically set when -fPIC is passed to the compiler.

Reviewed by:	dim, kib
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D1179
2014-11-21 02:05:48 +00:00
Konstantin Belousov 36bcb07ab5 Switch the defaults to not split the RLIMIT_STACK-sized initial thread
stack into the stacks of the created threads.  Add knob
LIBPTHREAD_SPLITSTACK_MAIN to restore the older behaviour.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 weeks
2014-09-24 12:39:12 +00:00
Rui Paulo 585bf8ae67 Fix typo in a comment. 2014-09-02 18:21:19 +00:00
Konstantin Belousov 6c8ce3bfce Add a knob LIBPTHREAD_BIGSTACK_MAIN, which instructs libthr to leave
the whole RLIMIT_STACK-sized region of the kernel-allocated stack as
the stack of main thread.

By default, the main thread stack is clamped at 2MB (4MB on 64bit
ABIs) and the rest is used for other threads stack allocation.  Since
there is no programmatic way to adjust the size of the main thread
stack, pthread_attr_setstacksize() is too late, the knob allows user
to manage the main stack size both for single-threaded and
multi-threaded processes with the rlimit.

Reported by:	"Ivan A. Kosarev" <ivan@ivan-labs.com>
Tested by:	dim
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2014-08-13 05:53:41 +00:00
Konstantin Belousov f6abec6c64 Style.
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2014-08-13 05:47:49 +00:00
Konstantin Belousov 1c70d00733 Right now, the rtld prefork hook locks the rtld bind lock in the read
mode.  This allows the binder to be functional in the child after the
fork (assuming no lazy loading of a filter is needed), but other rtld
services which require write lock on rtld_bind_lock cause deadlock, if
called by child.

Change the _rtld_atfork() to lock the bind lock in write mode, making
the rtld fully functional after the fork.

Pre-resolve the symbols which are called by the libthr' fork()
interposer, since dynamic resolution causes deadlock due to the
rtld_bind_lock already owned in the write mode.

Reported and tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2014-05-24 10:23:06 +00:00
Konstantin Belousov 082aa03e4b In _pthread_kill(), if passed pthread is current thread, do not send
the signal second time, by adding the missed else before if statement.

While there, postpone initializing local curthread variable until
passed signal number is checked for validity.

Submitted by:	John Wolfe <jlw@xinuos.com>
PR:	threads/186309
MFC after:	1 week
2014-02-01 18:13:18 +00:00
Konstantin Belousov 0a9655a082 If check_deferred_signal() execution needs binding of PLT symbol,
unlocking the rtld bind lock results in the processing of ast and
recursing into the check_deferred_signal().  Nested execution of
check_deferred_signal() delivers the signal to user code and clears
si_signo.  On return, top-level check_deferred_signal() frame
continues delivering the same signal one more time, but now with zero
si_signo.

Fix this by adding a flag to indicate that deferred delivery is
running, so check_deferred_signal() should avoid doing anything. Since
user signal handler is allowed to modify the passed machine context to
make return from the signal handler to cause arbitrary jump, or do
longjmp(). For this case, also clear the flag in thr_sighandler(),
since kernel signal delivery means that nested delivery code should
not run right now.

Reported by:	Vitaly Magerya <vmagerya@gmail.com>
Reviewed by:	davidxu, jilles
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2013-11-23 15:48:17 +00:00
Konstantin Belousov a0b9cbc8a2 The SUSv4tc1 requires that pthread_setcancelstate() shall be not a
cancellation point.  When enabling the cancellation, only process the
pending cancellation for asynchronous mode.

Reported and reviewed by:	Kohji Okuno <okuno.kohji@jp.panasonic.com>
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2013-06-19 04:47:41 +00:00
Konstantin Belousov 91ddaeb725 Since the cause of the problems with the __fillcontextx() was
identified, unify the code of check_deferred_signal() for all
architectures, making the variant under #ifdef x86 common.

Tested by:	marius (sparc64)
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2013-06-03 04:22:42 +00:00
Konstantin Belousov 55a1911ef2 The getcontext() from the __fillcontextx() call in the
check_deferred_signal() returns twice, since handle_signal() emulates
the return from the normal signal handler by sigreturn(2)ing the
passed context.  Second return is performed on the destroyed stack
frame, because __fillcontextx() has already returned.  This causes
undefined and bad behaviour, usually the victim thread gets SIGSEGV.

Avoid nested frame and the need to return from it by doing direct call
to getcontext() in the check_deferred_signal() and using a new private
libc helper __fillcontextx2() to complement the context with the
extended CPU state if the deferred signal is still present.

The __fillcontextx() is now unused, but is kept to allow older
libthr.so to be used with the new libc.

Mark __fillcontextx() as returning twice [1].

Reported by:	pgj
Pointy hat to:	kib
Discussed with:	dim
Tested by:	pgj, dim
Suggested by:	jilles [1]
MFC after:	1 week
2013-05-28 04:54:16 +00:00
Konstantin Belousov 5b1dd97092 Partially apply the capitalization of the heading word of the sequence
and fix typo.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2013-05-27 18:45:45 +00:00
David Xu 8096915018 Return one-based key so that user can check if the key is ever allocated
in the first place.

Initial patch submitted by: phk
2013-05-16 03:01:04 +00:00
David Xu 66f6c2721d Fix return value for setcontext and swapcontext. 2013-05-09 04:41:03 +00:00
Jilles Tjoelker da7d2afb6d Add accept4() system call.
The accept4() function, compared to accept(), allows setting the new file
descriptor atomically close-on-exec and explicitly controlling the
non-blocking status on the new socket. (Note that the latter point means
that accept() is not equivalent to any form of accept4().)

The linuxulator's accept4 implementation leaves a race window where the new
file descriptor is not close-on-exec because it calls sys_accept(). This
implementation leaves no such race window (by using falloc() flags). The
linuxulator could be fixed and simplified by using the new code.

Like accept(), accept4() is async-signal-safe, a cancellation point and
permitted in capability mode.
2013-05-01 20:10:21 +00:00
David Xu 9ae844e124 Remove extra code for SA_RESETHAND, it is not needed because kernel has
already done this.
2013-04-28 03:13:45 +00:00
Jilles Tjoelker 3cb14a8923 libthr: Fix a parameter name in an internal header file. 2013-04-27 14:21:36 +00:00
David Xu 31e9d5b85e Remove debug code. 2013-04-18 05:58:07 +00:00
David Xu 8bbeb7e9e0 Avoid copying memory if SIGCANCEL is not masked. 2013-04-18 05:56:00 +00:00
David Xu acad2b1e22 Revert revision 249323, the PR/177624 is confusing, that bug is caused
by using buggy getcontext/setcontext on same stack, while swapcontext
normally works on different stack, there is no such a problem.
2013-04-18 05:12:11 +00:00
Jilles Tjoelker 706b04b66f libthr: Remove _thr_rtld_fini(), unused since r245630. 2013-04-12 19:47:32 +00:00
David Xu 31c18e29cc swapcontext wrapper can not be implemented in C, the stack pointer saved in
the context becomes invalid when the function returns, same as setjmp,
it must be implemented in assemble language, see discussions in PR
misc/177624.
2013-04-10 02:40:03 +00:00
Jilles Tjoelker b18943f3b4 libthr: Always use the threaded rtld lock implementation.
The threaded rtld lock implementation is faster even in the single-threaded
case because it postpones signal handlers via THR_CRITICAL_ENTER and
THR_CRITICAL_LEAVE instead of calling sigprocmask(2).

As a result, exception handling becomes faster in single-threaded
applications linked with libthr.

Reviewed by:	kib
2013-01-18 23:08:40 +00:00
David Xu a7b84c6512 In suspend_common(), don't wait for a thread which is in creation, because
pthread_suspend_all_np() may have already suspended its parent thread.
Add locking code in pthread_suspend_all_np() to only allow one thread
to suspend other threads, this eliminates a deadlock where two or more
threads try to suspend each others.
2012-08-27 03:09:39 +00:00
David Xu 0aa81bff0b Eliminate redundant code, _thr_spinlock_init() has already been called
in init_private(), don't call it again in fork() wrapper.
2012-08-23 05:15:15 +00:00
David Xu d65f1abca7 Implement syscall clock_getcpuclockid2, so we can get a clock id
for process, thread or others we want to support.
Use the syscall to implement POSIX API clock_getcpuclock and
pthread_getcpuclockid.

PR:	168417
2012-08-17 02:26:31 +00:00
David Xu aa75bc577a Do defered mutex wakeup once. 2012-08-12 00:56:56 +00:00
David Xu e220a13ab9 MFp4:
Further decreases unexpected context switches by defering mutex wakeup
until internal sleep queue lock is released.
2012-08-11 23:17:02 +00:00
David Xu 5674256c7f Don't forget to initialize return value. 2012-07-20 05:47:12 +00:00
David Xu ec225efc58 Simplify code by replacing _thr_ref_add() with _thr_find_thread(). 2012-07-20 03:37:19 +00:00
David Xu 340e384de9 Eliminate duplicated code. 2012-07-20 03:27:07 +00:00
David Xu 30dd4f448c Don't assign same value. 2012-07-20 03:22:17 +00:00
David Xu 670bc18dfe Eliminate duplicated code. 2012-07-20 03:16:52 +00:00
David Xu 7e0cf81bc9 Eliminate duplicated code. 2012-07-20 03:00:41 +00:00
David Xu 12dbbf86f8 Don't forget to release a thread reference count,
replace _thr_ref_add() with _thr_find_thread(),
so reference count is no longer needed.

MFC after:	3 days
2012-07-20 01:56:14 +00:00
David Xu e3b090f037 Return EBUSY for PTHREAD_MUTEX_ADAPTIVE_NP too when the mutex could not
be acquired.

PR:	168317
MFC after:	3 days
2012-05-27 01:24:51 +00:00
David Xu fa782a2611 Create a common function lookup() to search a chan, this eliminates
redundant SC_LOOKUP() calling.
2012-05-10 09:30:37 +00:00
David Xu 173943ace3 Fix mis-merged line, move SC_LOOKUP() call to
upper level.
2012-05-05 23:51:24 +00:00
David Xu 84ac0fb8ca MFp4:
Enqueue thread in LIFO, this can cause starvation, but it gives better
performance. Use _thr_queuefifo to control the frequency of FIFO vs LIFO,
you can use environment string LIBPTHREAD_QUEUE_FIFO to configure the
variable.
2012-05-03 09:17:31 +00:00
George V. Neville-Neil 6e047a2426 Set SIGCANCEL to SIGTHR as part of some cleanup of DTrace code.
Reviewed by:	davidxu@
MFC after:	1 week
2012-04-18 16:29:55 +00:00
David Xu 17ce606321 umtx operation UMTX_OP_MUTEX_WAKE has a side-effect that it accesses
a mutex after a thread has unlocked it, it event writes data to the mutex
memory to clear contention bit, there is a race that other threads
can lock it and unlock it, then destroy it, so it should not write
data to the mutex memory if there isn't any waiter.
The new operation UMTX_OP_MUTEX_WAKE2 try to fix the problem. It
requires thread library to clear the lock word entirely, then
call the WAKE2 operation to check if there is any waiter in kernel,
and try to wake up a thread, if necessary, the contention bit is set again
by the operation. This also mitgates the chance that other threads find
the contention bit and try to enter kernel to compete with each other
to wake up sleeping thread, this is unnecessary. With this change, the
mutex owner is no longer holding the mutex until it reaches a point
where kernel umtx queue is locked, it releases the mutex as soon as
possible.
Performance is improved when the mutex is contensted heavily.  On Intel
i3-2310M, the runtime of a benchmark program is reduced from 26.87 seconds
to 2.39 seconds, it even is better than UMTX_OP_MUTEX_WAKE which is
deprecated now. http://people.freebsd.org/~davidxu/bench/mutex_perf.c
2012-04-05 02:24:08 +00:00
Jilles Tjoelker 91792417bb libthr: In the atfork handlers for signals, do not skip the last signal.
_SIG_MAXSIG works a bit unexpectedly: signals 1 till _SIG_MAXSIG are valid,
both bounds inclusive.

Reviewed by:	davidxu
MFC after:	1 week
2012-03-26 17:05:26 +00:00
David Xu 81cd726a95 Use clockid parameter instead of hard-coded CLOCK_REALTIME.
Reported by:	pjd
2012-03-19 00:07:10 +00:00
David Xu 1b008f5e51 Some software think a mutex can be destroyed after it owned it, for
example, it uses a serialization point like following:
	pthread_mutex_lock(&mutex);
	pthread_mutex_unlock(&mutex);
	pthread_mutex_destroy(&muetx);
They think a previous lock holder should have already left the mutex and
is no longer referencing it, so they destroy it. To be maximum compatible
with such code, we use IA64 version to unlock the mutex in kernel, remove
the two steps unlocking code.
2012-03-18 00:22:29 +00:00
David Xu e70bf9d5eb When destroying a barrier, waiting all threads exit the barrier,
this makes it possible a thread received PTHREAD_BARRIER_SERIAL_THREAD
immediately free memory area of the barrier.
2012-03-16 04:35:52 +00:00
David Xu 24c209494a Follow changes made in revision 232144, pass absolute timeout to kernel,
this eliminates a clock_gettime() syscall.
2012-02-27 13:38:52 +00:00
David Xu df1f1bae9e In revision 231989, we pass a 16-bit clock ID into kernel, however
according to POSIX document, the clock ID may be dynamically allocated,
it unlikely will be in 64K forever. To make it future compatible, we
pack all timeout information into a new structure called _umtx_time, and
use fourth argument as a size indication, a zero means it is old code
using timespec as timeout value, but the new structure also includes flags
and a clock ID, so the size argument is different than before, and it is
non-zero. With this change, it is possible that a thread can sleep
on any supported clock, though current kernel code does not have such a
POSIX clock driver system.
2012-02-25 02:12:17 +00:00
David Xu b13a8fa78f Use unused fourth argument of umtx_op to pass flags to kernel for operation
UMTX_OP_WAIT. Upper 16bits is enough to hold a clock id, and lower
16bits is used to pass flags. The change saves a clock_gettime() syscall
from libthr.
2012-02-22 03:22:49 +00:00
David Xu 879d152454 Check both seconds and nanoseconds are zero, only checking nanoseconds
is zero may trigger timeout too early. It seems a copy&paste bug.
2012-02-19 08:17:14 +00:00
David Xu 4c91ddd690 Make code more stable by checking NULL pointers. 2012-02-11 04:12:12 +00:00
David Xu e7004bf44d Plug a memory leak. When a cached thread is reused, don't clear sleep
queue pointers, just reuse it.

PR:		164828
MFC after:	1 week
2012-02-07 02:57:36 +00:00
Konstantin Belousov 10280ca601 Use getcontextx(3) internal API instead of getcontext(2) to provide
the signal handlers with the context information in the deferrred
case.

Only enable the use of getcontextx(3) in the deferred signal delivery
code on amd64 and i386. Sparc64 seems to have some undetermined issues
with interaction of alloca(3) and signal delivery.

Tested by:	flo (who also provided sparc64 harware access for me), pho
Discussed with:	marius
MFC after:	1 month
2012-01-21 18:06:18 +00:00
David Xu 7859df8e67 Pass CVWAIT flags to kernel, this should handle
timeout correctly for pthread_cond_timedwait when
it uses kernel-based condition variable.

PR:	162403
Submitted by: jilles
MFC after: 3 days
2011-11-17 01:43:50 +00:00
Alexander Kabaev a805bbe21a Do not set thread name to less than informative 'initial thread'. 2011-06-19 13:35:36 +00:00
Ryan Stone aad93b043a r179417 introduced a bug into pthread_once(). Previously pthread_once()
used a global pthread_mutex_t for synchronization.  r179417 replaced that
with an implementation that directly used atomic instructions and thr_*
syscalls to synchronize callers to pthread_once.  However, calling
pthread_mutex_lock on the global mutex implicitly ensured that
_thr_check_init() had been called but with r179417 this was no longer
guaranteed.  This meant that if you were unlucky enough to have your first
call into libthr be a call to pthread_once(), you would segfault when
trying to access the pointer returned by _get_curthread().

The fix is to explicitly call _thr_check_init() from pthread_once().

Reviewed by:	davidxu
Approved by:	emaste (mentor)
MFC after:	1 week
2011-04-20 14:19:34 +00:00
Jung-uk Kim 678b238c85 Introduce a non-portable function pthread_getthreadid_np(3) to retrieve
calling thread's unique integral ID, which is similar to AIX function of
the same name.  Bump __FreeBSD_version to note its introduction.

Reviewed by:	kib
2011-02-07 21:26:46 +00:00
David Xu 65a6aaf1f3 Fix a typo.
Submitted by:	avg
2011-01-11 01:57:02 +00:00
Konstantin Belousov fad128db86 For the process that already loaded libthr but still not initialized
threading, fall back to libc method of performing
__pthread_map_stacks_exec() job.

Reported and tested by:	Mykola Dzham <i levsha me>
2011-01-10 16:10:25 +00:00
Konstantin Belousov da2fcff746 Implement the __pthread_map_stacks_exec() for libthr.
Stack creation code is changed to call _rtld_get_stack_prot() to get
the stack protection right. There is a race where thread is created
during dlopen() of dso that requires executable stacks. Then,
_rtld_get_stack_prot() may return PROT_READ | PROT_WRITE, but thread
is still not linked into the thread list. In this case, the callback
misses the thread stack, and rechecks the required protection
afterward.

Reviewed by:	davidxu
2011-01-09 12:38:40 +00:00
David Xu ebc8e8fd7f Return 0 instead of garbage value.
Found by:	clang static analyzer
2011-01-06 08:13:30 +00:00
David Xu 1f6f22dfec Because sleepqueue may still being used, we should always check wchan with
queue locked.
2011-01-04 05:35:19 +00:00
David Xu e29ba4c2db Always clear flag PMUTEX_FLAG_DEFERED when unlocking, as it is only
significant for lock owner.
2010-12-24 07:41:39 +00:00
David Xu 0126aea6ad Add sleep queue code. 2010-12-22 05:03:24 +00:00
David Xu d1078b0b03 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.
2010-12-22 05:01:52 +00:00
David Xu 1d1486408b Use sysctl kern.sched.cpusetsize to retrieve size of kernel cpuset. 2010-11-02 02:13:13 +00:00
David Xu 6ed79f06f4 Return previous sigaction correctly.
Submitted by:	avg
2010-10-29 09:35:36 +00:00
David Xu 322a8adaa3 Remove local variable 'first', instead check signal number in memory,
because the variable can be in register, second checking the variable
may still return true, however this is unexpected.
2010-10-29 07:04:45 +00:00
David Xu 67753965a8 Check small set and reject it, this is how kernel did. Always use the
size kernel is using.
2010-10-27 09:59:43 +00:00
David Xu 4a5478709b - Revert r214409.
- Use long word to figure out sizeof kernel cpuset, hope it works.
2010-10-27 09:29:03 +00:00
David Xu e96b4de80e Remove locking and unlock in pthread_mutex_destroy, because
it can not fix race condition in application code, as a result,
the problem described in PR threads/151767 is avoided.
2010-10-27 04:19:07 +00:00
David Xu 65df457797 Fix typo. 2010-10-25 11:16:50 +00:00
David Xu 7f25f6c72d Get cpuset in pthread_attr_get_np() and free it in pthread_attr_destroy().
MFC after:	7 days
2010-10-25 09:16:04 +00:00
David Xu de1e74c6a5 Revert revision 214007, I realized that MySQL wants to resolve
a silly rwlock deadlock problem, the deadlock is caused by writer
waiters, if a thread has already locked a reader lock, and wants to
acquire another reader lock, it will be blocked by writer waiters,
but we had already fixed it years ago.
2010-10-20 02:34:02 +00:00
David Xu a24bcc04b2 Set default type to PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, this
is the type we are using.
2010-10-18 23:37:56 +00:00
David Xu 7047ff7588 s/||/&& 2010-10-18 05:15:26 +00:00
David Xu a6b9b59e04 Add pthread_rwlockattr_setkind_np and pthread_rwlockattr_getkind_np, the
functions set or get pthread_rwlock type, current supported types are:
   PTHREAD_RWLOCK_PREFER_READER_NP,
   PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
   PTHREAD_RWLOCK_PREFER_WRITER_NP,
default is PTHREAD_RWLOCK_PREFER_WRITER_NONCECURSIVE_NP, this maintains
binary compatible with old code.
2010-10-18 05:09:22 +00:00
David Xu 722488013d change code to use unwind.h. 2010-09-30 12:59:56 +00:00
David Xu ec92603cf9 Check invalid mutex in _mutex_cv_unlock. 2010-09-29 06:06:58 +00:00
David Xu bbb64c2143 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.
2010-09-28 04:57:56 +00:00
David Xu 1d5b5089aa Report death event to debugger before moving to gc list, otherwise
debugger may can not find it on thread list.
2010-09-26 06:45:24 +00:00
David Xu 8be6abcdc6 Only access unwind_disabled when _PTHREAD_FORCED_UNWIND is defined. 2010-09-25 09:43:24 +00:00
David Xu 9f1dc4c107 Add missing field. 2010-09-25 08:36:46 +00:00
David Xu 8690b9f6dd Because old _pthread_cleanup_push/pop do not have frame address,
it is incompatible with stack unwinding code, if they are invoked,
disable stack unwinding for current thread, and when thread is
exiting, print a warning message.
2010-09-25 06:27:09 +00:00
David Xu 6f066bb387 Simplify code, and in while loop, fix operator to match the unwinding
direction.
2010-09-25 04:21:31 +00:00
David Xu f4213b9006 To support stack unwinding for cancellation points, add -fexceptions flag
for them, two functions _pthread_cancel_enter and _pthread_cancel_leave
are added to let thread enter and leave a cancellation point, it also
makes it possible that other functions can be cancellation points in
libraries without having to be rewritten in libthr.
2010-09-25 01:57:47 +00:00
David Xu e5c66a0d9e inline testcancel() into thr_cancel_leave(), because cancel_pending is
almost false, this makes a slight better branch predicting.
2010-09-24 13:01:01 +00:00
David Xu 93ea4a71bf In most cases, cancel_point and cancel_async needn't be checked again,
because cancellation is almostly checked at cancellation points.
2010-09-24 07:52:07 +00:00
David Xu 81f3e99c56 If we are at cancellation point, always work as deferred mode despite
whether asynchronous mode is turned on or not, this always gives us a
chance to decide whether thread should be canceled or not in
cancellation points.
2010-09-21 06:47:04 +00:00
David Xu 4173ebef4f Because atfork lock is held while forking, a thread cancellation triggered
by atfork handler is unsafe, use intenal flag no_cancel to disable it.
2010-09-19 09:03:11 +00:00
David Xu 7c243121b7 Fix typo. 2010-09-19 08:55:36 +00:00
David Xu a5793db975 - _Unwind_Resume function is not used, remove it.
- Use a store barrier to make sure uwl_forcedunwind is lastest thing
  other threads can see.
- Add some comments.
2010-09-19 05:42:29 +00:00
David Xu 4da1da4b6e Fix a race condition when finding stack unwinding functions. 2010-09-19 05:19:47 +00:00
David Xu 3832fd24f1 add code to support stack unwinding when thread exits. note that only
defer-mode cancellation works, asynchrnous mode does not work because
it lacks of libuwind's support. stack unwinding is not enabled unless
LIBTHR_UNWIND_STACK is defined in Makefile.
2010-09-15 02:56:32 +00:00
David Xu 707ee8154d Move back IN_GCLIST flag into field tlflags, since thread list and gc list
still share same lock.
2010-09-15 01:21:30 +00:00
David Xu 7820a71113 Don't compare thread pointers again. 2010-09-13 11:58:42 +00:00
David Xu cbadc1d7ad Fix copy&paste problem. 2010-09-13 11:57:46 +00:00
David Xu b749a04db3 PS_DEAD state needs not be checked because _thr_find_thread() has already
checked it.
2010-09-13 07:18:00 +00:00
David Xu a9b764e218 Convert thread list lock from mutex to rwlock. 2010-09-13 07:03:01 +00:00
David Xu 83c9e0893f Because POSIX does not allow EINTR to be returned from sigwait(),
add a wrapper for it in libc and rework the code in libthr, the
system call still can return EINTR, we keep this feature.

Discussed on: thread
Reviewed by:  jilles
2010-09-10 01:47:37 +00:00
David Xu 17dce7e108 To avoid possible race condition, SIGCANCEL is always sent except the
thread is dead.
2010-09-08 02:18:20 +00:00
David Xu cb4a1047ce Fix off-by-one error in function _thr_sigact_unload, also disable the
function, it seems some gnome application tends to crash if we
unregister sigaction automatically.
2010-09-06 03:00:54 +00:00
David Xu 21a9296f63 Remove incorrect comments, also make sure signal is
disabled when unregistering sigaction.
2010-09-01 13:22:55 +00:00
David Xu 12c61c22ce In function __pthread_cxa_finalize(), also make code for removing
atfork handler be async-signal safe.
2010-09-01 07:09:46 +00:00
David Xu a523216bc6 pthread_atfork should acquire writer lock and protect the code
with critical region.
2010-09-01 03:55:10 +00:00
David Xu ada33a6e36 Change atfork lock from mutex to rwlock, also make mutexes used by malloc()
module private type, when private type mutex is locked/unlocked, thread
critical region is entered or leaved. These changes makes fork()
async-signal safe which required by POSIX. Note that user's atfork handler
still needs to be async-signal safe, but it is not problem of libthr, it
is user's responsiblity.
2010-09-01 03:11:21 +00:00
David Xu 02c3c85869 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.
2010-09-01 02:18:33 +00:00