Add another check for thread library initialization (jdp, we
really need a way to get _thread_init called at program start
before any constructors are run).
_foo - wrapped system call
foo - weak definition to _foo
and for cancellation points:
_foo - wrapped system call
__foo - enter cancellation point, call _foo(), leave
cancellation point
foo - weak definition to __foo
Change use of global _thread_run to call a function to get the
currently running thread.
Make all pthread_foo functions weak definitions to _pthread_foo,
where _pthread_foo is the implementation. This allows an application
to provide its own pthread functions.
Provide slightly different versions of pthread_mutex_lock and
pthread_mutex_init so that we can tell the difference between
a libc mutex and an application mutex. Threads holding mutexes
internal to libc should never be allowed to exit, call signal
handlers, or cancel.
Approved by: -arch
referenced to by libgcc.a.
This is needed when linking statically as SVR4 (ie, ELF) behavior is to only
link in a module if it satisfies an undefined strong reference from somewhere.
(this surprises a lot of people) Things are different when using shared libs,
the entire library and its modules and their symbols are available at run-time
(when the weak reference is seen to still be unsatisfied and is satisfied on
the spot), this is not the case with static libs.
Thus one can have a static binary with unresolved week references, and at
run-time dereference a NULL pointer.
Submitted by: eischen
Submitted by: "Peter Avalos" <pavalos@theshell.com>
Reviewed by: /sbin/md5 [*]
[*] This line appears courtesy of Mr. Warner Losch, all rights reversed.
global time of day. This costs us nothing, but is a bit of a hack
to work around a process blocking and not having the time updated
by an ITIMER_PROF signal.
PR: 23679
executed at least once, fixing pthread_mutex_lock() for recursive
mutex lock attempts.
Correctly set a threads signal mask while it is executing a signal
handler. The mask should be the union of its current mask, the
signal being handled, and the mask from the signal action.
Reported by: Dan Nelson <dnelson@emsphone.com>
MFC Candidate
was not getting properly initialized in pthread_cond_signal()
and pthread_cond_broadcast(). Reportedly, this can cause
an application to die.
MFC candidate
Submitted by: ade
the kernel to (re)use the alternate signal stack. In this
case, we don't return normally from the signal handler,
so the kernel still thinks we are using the signal stack.
The fixes a nasty bug where the signal handler can start
fiddling with the stack of a thread while the handler is
actually running on the same stack.
MFC candidate
file descriptors needing to be polled (Doh!). Reported
by Dan Nelson <dnelson@emsphone.com>.
Don't install and start the scheduling timer until the
first thread is created. This prevents the overhead of
having a periodic scheduling signal in a single threaded
program. Reported by Dan Nelson <dnelson@emsphone.com>.
Allow builtin longjmps out of application installed
signal handlers without the need perform any post-handler
cleanup:
o Change signal handling to save the threads interrupted
context on the stack. The threads current context is
now always stored in the same place (in the pthread).
If and when a signal handler returns, the interrupted
context is copied back to the storage area in the pthread.
o Before calling invoking a signal handler for a thread,
back the thread out of any internal waiting queues
(mutex, CV, join, etc) to which it belongs.
Rework uthread_info.c a bit to make it easier to change
the format of a thread dump.
Use an alternal signal stack for the thread library's
signal handler. This allows us to fiddle with the main
threads stack without fear of it being in use.
Reviewed by: jasone
into an infinite loop when a timeout value is supplied
and the timeout expires.
Reported by: Dan Nelson <dnelson@emsphone.com>
Reviewed by: jasone, jlemon
by sigwait(). This prevents a signal from being sent to the process
when there are no application installed signal handlers.
Correct a typo in sigwait (foo -> foo[i]).
adding a signal frame to a thread, be sure to label the context
correctly so we don't restore an uninitialized process mask.
Reported by: kimc@W8HD.ORG and Andrey Rouskol <anry@sovintel.ru>
thread switches should be on par with that under scheduler
activations.
o Timing is achieved through the use of a fixed interval
timer (ITIMER_PROF) to count scheduling ticks instead
of retrieving the time-of-day upon every thread switch
and calculating elapsed real time.
o Polling for I/O readiness is performed once for each
scheduling tick instead of every thread switch.
o The non-signal saving/restoring versions of setjmp/longjmp
are used to save and restore thread contexts. This may
allow the removal of _THREAD_SAFE macros from setjmp()
and longjmp() - needs more investigation.
Change signal handling so that signals are handled in the
context of the thread that is receiving the signal. When
signals are dispatched to a thread, a special signal handling
frame is created on top of the target threads stack. The
frame contains the threads saved state information and a new
context in which the thread can run. The applications signal
handler is invoked through a wrapper routine that knows how
to restore the threads saved state and unwind to previous
frames.
Fix interruption of threads due to signals. Some states
were being improperly interrupted while other states were
not being interrupted. This should fix several PRs.
Signal handlers, which are invoked as a result of a process
signal (not by pthread_kill()), are now called with the
code (or siginfo_t if SA_SIGINFO was set in sa_flags) and
sigcontext_t as received from the process signal handler.
Modify the search for a thread to which a signal is delivered.
The search algorithm is now:
o First thread found in sigwait() with signal in wait mask.
o First thread found sigsuspend()'d on the signal.
o Current thread if signal is unmasked.
o First thread found with signal unmasked.
Collapse machine dependent support into macros defined in
pthread_private.h. These should probably eventually be moved
into separate MD files.
Change the range of settable priorities to be compliant with
POSIX (0-31). The threads library uses higher priorities
internally for real-time threads (not yet implemented) and
threads executing signal handlers. Real-time threads and
threads running signal handlers add 64 and 32, respectively,
to a threads base priority.
Some other small changes and cleanups.
PR: 17757 18559 21943
Reviewed by: jasone
pthread_cond_signal(), pthread_cond_broadcast(), and pthread_cond_timedwait().
Do not dump core in pthread_cond_timedwait() (due to a NULL pointer
dereference) if attempting to wait on an uninitialized condition variable.
PR: bin/18099
not have a user-supplied signal handler, when a signal is delivered, one
thread will receive the signal, and then the code reverts to having no
signal handler for the signal. This can leave the other sigwait()ing
threads stranded permanently if the signal is later ignored, or can result
in process termination when the process should have delivered the signal to
one of the threads in sigwait().
To fix this problem, maintain a count of sigwait()ers for each signal that
has no default signal handler. Use the count to correctly install/uninstall
dummy signal handlers.
Reviewed by: deischen
not allowed to return EINTR, but use of pthread_suspend_np() could cause
EINTR to be returned. To fix this, restructure pthread_suspend_np() so that
it does not interrupt a thread that is waiting on a mutex or condition, and
keep enough state around that pthread_resume_np() can fix things up
afterwards.
Reviewed by: deischen
thread waiting on an event (I/O, condvar, etc) will, when resumed using
pthread_resume_np, return with EINTR. For example, suspending and resuming
a thread blocked on read() will not requeue the thread for the read, but
will return -1 with errno = EINTR. If the suspended thread is in a critical
region, the thread is suspended as soon as it leaves the critical region.
Fix a bogon in pthread_kill() where a signal was being delivered twice
to threads waiting in sigwait().
Reported by (suspend/resume bug): jdp
Reviewed by: jasone
returning the error directly.
For sem_post(), make sure that the correct thread is woken up. This has
unfortunate performance implications, but is necessary for POSIX compliance.
Approved by: jkh
just use _foo() <-- foo(). In the case of a libpthread that doesn't do
call conversion (such as linuxthreads and our upcoming libpthread), this
is adequate. In the case of libc_r, we still need three names, which are
now _thread_sys_foo() <-- _foo() <-- foo().
Convert all internal libc usage of: aio_suspend(), close(), fsync(), msync(),
nanosleep(), open(), fcntl(), read(), and write() to _foo() instead of foo().
Remove all internal libc usage of: creat(), pause(), sleep(), system(),
tcdrain(), wait(), and waitpid().
Make thread cancellation fully POSIX-compliant.
Suggested by: deischen
are not supported by this implementation, and the error return values
from sem_init(), sem_open(), sem_close(), and sem_unlink() reflect this.
Approved by: jkh