| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
this mirrors the stdio_impl.h cleanup. one header which is not
strictly needed, errno.h, is left in pthread_impl.h, because since
pthread functions return their error codes rather than using errno,
nearly every single pthread function needs the errno constants.
in a few places, rather than bringing in string.h to use memset, the
memset was replaced by direct assignment. this seems to generate much
better code anyway, and makes many functions which were previously
non-leaf functions into leaf functions (possibly eliminating a great
deal of bloat on some platforms where non-leaf functions require ugly
prologue and/or epilogue).
|
|
|
|
|
|
|
|
| |
to deal with the fact that the public headers may be used with pre-c99
compilers, __restrict is used in place of restrict, and defined
appropriately for any supported compiler. we also avoid the form
[restrict] since older versions of gcc rejected it due to a bug in the
original c99 standard, and instead use the form *restrict.
|
|
|
|
|
|
|
|
|
|
| |
some minor changes to how hard-coded sets for thread-related purposes
are handled were also needed, since the old object sizes were not
necessarily sufficient. things have gotten a bit ugly in this area,
and i think a cleanup is in order at some point, but for now the goal
is just to get the code working on all supported archs including mips,
which was badly broken by linux rejecting syscalls with the wrong
sigset_t size.
|
|
|
|
|
| |
due to the barrier, it's safe just to block signals in the new thread,
rather than blocking and unblocking in the parent thread.
|
| |
|
|
|
|
|
|
|
| |
if a timer thread leaves signals unblocked, any future attempt by the
main thread to prevent the process from being terminated by blocking
signals will fail, since the signal can still be delivered to the
timer thread.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
the new approach relies on the fact that the only ways to create
sigset_t objects without invoking UB are to use the sig*set()
functions, or from the masks returned by sigprocmask, sigaction, etc.
or in the ucontext_t argument to a signal handler. thus, as long as
sigfillset and sigaddset avoid adding the "protected" signals, there
is no way the application will ever obtain a sigset_t including these
bits, and thus no need to add the overhead of checking/clearing them
when sigprocmask or sigaction is called.
note that the old code actually *failed* to remove the bits from
sa_mask when sigaction was called.
the new implementations are also significantly smaller, simpler, and
faster due to ignoring the useless "GNU HURD signals" 65-1024, which
are not used and, if there's any sanity in the world, never will be
used.
|
|
|
|
|
|
| |
otherwise we cannot support an application's desire to use
asynchronous cancellation within the callback function. this change
also slightly debloats pthread_create.c.
|
| |
|
|
|
|
|
| |
calling pthread_exit from, or pthread_cancel on, the timer callback
thread will no longer destroy the timer.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
since timer_create is no longer allocating a structure for the timer_t
and simply using the kernel timer id, it was impossible to specify the
timer_t as the argument to the signal handler. the solution is to pass
the null sigevent pointer on to the kernel, rather than filling it in
userspace, so that the kernel does the right thing. however, that
precludes the clever timerid-versus-threadid encoding we were doing.
instead, just assume timerids are below 1M and thread pointers are
above 1M. (in perspective: timerids are sequentially allocated and
seem limited to 32k, and thread pointers are at roughly 3G.)
|
| |
|
|
|
|
|
| |
this is necessary in order to avoid breaking timer_getoverrun in the
last run of the timer event handler, if it has not yet finished.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
instead of allocating a userspace structure for signal-based timers,
simply use the kernel timer id. we use the fact that thread pointers
will always be zero in the low bit (actually more) to encode integer
timerid values as pointers.
also, this change ensures that the timer_destroy syscall has completed
before the library timer_destroy function returns, in case it matters.
|
|
|
|
|
|
|
|
|
| |
the major idea of this patch is not to depend on having the timer
pointer delivered to the signal handler, and instead use the thread
pointer to get the callback function address and argument. this way,
the parent thread can make the timer_create syscall while the child
thread is starting, and it should never have to block waiting for the
barrier.
|
|
|
|
|
| |
this allows small programs which only create times, but never delete
them, to use simple_malloc instead of the full malloc.
|
|
this implementation is superior to the glibc/nptl implementation, in
that it gives true realtime behavior. there is no risk of timer
expiration events being lost due to failed thread creation or failed
malloc, because the thread is created as time creation time, and
reused until the timer is deleted.
|