Commit Graph

258 Commits

Author SHA1 Message Date
Rich Felker ea200e38bd support cputime clocks for processes/threads other than self
apparently these features have been in Linux for a while now, so it
makes sense to support them. the bit twiddling seems utterly illogical
and wasteful, especially the negation, but that's how the kernel folks
chose to encode pids/tids into the clock id.
2013-06-08 11:36:41 -04:00
Rich Felker 44b4d09fc0 ensure that thread dtv pointer is never null to optimize __tls_get_addr 2013-06-03 16:35:59 -04:00
Rich Felker 2c074b0d6c transition to using functions for internal signal blocking/restoring
there are several reasons for this change. one is getting rid of the
repetition of the syscall signature all over the place. another is
sharing the constant masks without costly GOT accesses in PIC.

the main motivation, however, is accurately representing whether we
want to block signals that might be handled by the application, or all
signals.
2013-04-26 19:48:01 -04:00
Rich Felker d674f8582a prevent code from running under a thread id which already gave ESRCH 2013-04-26 17:51:22 -04:00
Rich Felker 47d2bf5103 synccall signal handler need not handle dead threads anymore
they have already blocked signals before decrementing the thread
count, so the code being removed is unreachable in the case where the
thread is no longer counted.
2013-04-26 17:46:58 -04:00
Rich Felker 082fb4e9bf fix clobbering of signal mask when creating thread with sched attributes
this was simply a case of saving the state in the wrong place.
2013-04-26 17:30:32 -04:00
Rich Felker d0ba09837b make last thread's pthread_exit give exit(0) a consistent state
the previous few commits ended up leaving the thread count and signal
mask wrong for atexit handlers and stdio cleanup.
2013-04-26 16:16:04 -04:00
Rich Felker c3a6839ce9 use atomic decrement rather than cas in pthread_exit thread count
now that blocking signals prevents any application code from running
while the last thread is exiting, the cas logic is no longer needed to
prevent decrementing below zero.
2013-04-26 16:05:39 -04:00
Rich Felker 6e531f999a add comments on some of the pthread_exit logic 2013-04-26 16:04:30 -04:00
Rich Felker 23f21c304f always block signals in pthread_exit before decrementing thread count
the thread count (1+libc.threads_minus_1) must always be greater than
or equal to the number of threads which could have application code
running, even in an async-signal-safe sense. there is at least one
dangerous race condition if this invariant fails to hold: dlopen could
allocate too little TLS for existing threads, and a signal handler
running in the exiting thread could claim the allocated TLS for itself
(via __tls_get_addr), leaving too little for the other threads it was
allocated for and thereby causing out-of-bounds access.

there may be other situations where it's dangerous for the thread
count to be too low, particularly in the case where only one thread
should be left, in which case locking may be omitted. however, all
such code paths seem to arise from undefined behavior, since
async-signal-unsafe functions are not permitted to be called from a
signal handler that interrupts pthread_exit (which is itself
async-signal-unsafe).

this change may also simplify logic in __synccall and improve the
chances of making __synccall async-signal-safe.
2013-04-26 15:47:44 -04:00
Rich Felker ced64995c2 fix type error in pthread_create, introduced with pthread_getattr_np 2013-04-06 01:15:08 -04:00
Rich Felker 14a835b386 implement pthread_getattr_np
this function is mainly (purely?) for obtaining stack address
information, but we also provide the detach state since it's easy to
do anyway.
2013-03-31 23:25:55 -04:00
Rich Felker ccc7b4c3a1 remove __SYSCALL_SSLEN arch macro in favor of using public _NSIG
the issue at hand is that many syscalls require as an argument the
kernel-ABI size of sigset_t, intended to allow the kernel to switch to
a larger sigset_t in the future. previously, each arch was defining
this size in syscall_arch.h, which was redundant with the definition
of _NSIG in bits/signal.h. as it's used in some not-quite-portable
application code as well, _NSIG is much more likely to be recognized
and understood immediately by someone reading the code, and it's also
shorter and less cluttered.

note that _NSIG is actually 65/129, not 64/128, but the division takes
care of throwing away the off-by-one part.
2013-03-26 23:07:31 -04:00
Rich Felker 72768ea99e fix stale locks left behind when pthread_create fails
this bug seems to have been around a long time.
2013-02-01 22:25:19 -05:00
Rich Felker 077549e0d4 if pthread_create fails, it must not attempt mmap if there is no mapping
this bug was introduced when support for application-provided stacks
was originally added.
2013-02-01 22:23:24 -05:00
Rich Felker d5142642b8 pthread stack treatment overhaul for application-provided stacks, etc.
the main goal of these changes is to address the case where an
application provides a stack of size N, but TLS has size M that's a
significant portion of the size N (or even larger than N), thus giving
the application less stack space than it expected or no stack at all!

the new strategy pthread_create now uses is to only put TLS on the
application-provided stack if TLS is smaller than 1/8 of the stack
size or 2k, whichever is smaller. this ensures that the application
always has "close enough" to what it requested, and the threshold is
chosen heuristically to make sure "sane" amounts of TLS still end up
in the application-provided stack.

if TLS does not fit the above criteria, pthread_create uses mmap to
obtain space for TLS, but still uses the application-provided stack
for actual call frame stack. this is to avoid wasting memory, and for
the sake of supporting ugly hacks like garbage collection based on
assumptions that the implementation will use the provided stack range.

in order for the above heuristics to ever succeed, the amount of TLS
space wasted on POSIX TSD (pthread_key_create based) needed to be
reduced. otherwise, these changes would preclude any use of
pthread_create without mmap, which would have serious memory usage and
performance costs for applications trying to create huge numbers of
threads using pre-allocated stack space. the new value of
PTHREAD_KEYS_MAX is the minimum allowed by POSIX, 128. this should
still be plenty more than real-world applications need, especially now
that C11/gcc-style TLS is now supported in musl, and most apps and
libraries choose to use that instead of POSIX TSD when available.

at the same time, PTHREAD_STACK_MIN has been decreased. it was
originally set to PAGE_SIZE back when there was no support for TLS or
application-provided stacks, and requests smaller than a whole page
did not make sense. now, there are two good reasons to support
requests smaller than a page: (1) applications could provide
pre-allocated stacks smaller than a page, and (2) with smaller stack
sizes, stack+TLS+TSD can all fit in one page, making it possible for
applications which need huge numbers of threads with minimal stack
needs to allocate exactly one page per thread. the new value of
PTHREAD_STACK_MIN, 2k, is aligned with the minimum size for
sigaltstack.
2013-02-01 22:10:40 -05:00
Rich Felker facc6acbfd replace __wake function with macro that performs direct syscall
this should generate faster and smaller code, especially with inline
syscalls. the conditional with cnt is ugly, but thankfully cnt is
always a constant anyway so it gets evaluated at compile time. it may
be preferable to make separate __wake and __wakeall macros without a
count argument.

priv flag is not used yet; private futex support still needs to be
done at some point in the future.
2013-02-01 16:41:53 -05:00
Rich Felker 1c322f2f0a fix some restrict-qualifier mismatches in newly added interfaces
these should have little/no practical impact but they're needed for
strict conformance.
2012-11-27 09:44:30 -05:00
rofl0r 3fae236e00 powerpc: handle syscall error in clone.
sigsetjmp: store temporaries in jmp_buf rather than on stack.
2012-11-19 16:58:09 +01:00
Rich Felker 9565a349f2 fix powerpc asm not to store data in volatile space below stack pointer
it's essential to decrement the stack pointer before writing to new
stack space, rather than afterwards. otherwise there is a race
condition during which asynchronous code (signals) could clobber the
data being stored.

it may be possible to optimize the code further using stwu, but I
wanted to avoid making any changes to the actual stack layout in this
commit. further improvements can be made separately if desired.
2012-11-18 22:57:32 -05:00
Rich Felker 5c6443ac42 add stub versions of some missing optional pthread interfaces
priority inheritance is not yet supported, and priority protection
probably will not be supported ever unless there's serious demand for
it (it's a fairly heavy-weight feature).

per-thread cpu clocks would be nice to have, but to my knowledge linux
is still not capable of supporting them. glibc fakes them by using the
_process_ cpu-time clock and subtracting the thread creation time,
which gives seriously incorrect semantics (worse than not supporting
the feature at all), so until there's a way to do it right, it will
remain as a stub that always fails.
2012-11-17 18:42:16 -05:00
Rich Felker d1bf452d75 fix indention with spaces in powerpc asm 2012-11-14 14:27:51 -05:00
Rich Felker c6d441e3a2 Merge remote-tracking branch 'ppc-port/ppc-squashed' 2012-11-14 14:01:39 -05:00
rofl0r 1c8eb8bad7 PPC port cleaned up, static linking works well now. 2012-11-13 19:12:25 +01:00
Richard Pennington 7669d1e334 import preliminary ppc work by rdp. 2012-11-13 18:15:10 +01:00
Rich Felker c4a35f8c2a debloat src/thread tree but putting lots of junk in one file
POSIX includes mostly-useless attribute-get functions for each
attribute-set function, presumably out of some object-oriented
dogmatism. the get functions are not useful with the simple idiomatic
usage of attributes. there are of course possible valid uses of them
(like writing wrappers for pthread init functions that perform special
actions on the presence of certain attributes), but considering how
tiny these functions are anyway, little is lost by putting them all in
one file, and some build-time cost and archive-file-size benefits are
achieved.
2012-11-11 16:08:38 -05:00
Rich Felker 1e21e78bf7 add support for thread scheduling (POSIX TPS option)
linux's sched_* syscalls actually implement the TPS (thread
scheduling) functionality, not the PS (process scheduling)
functionality which the sched_* functions are supposed to have.
omitting support for the PS option (and having the sched_* interfaces
fail with ENOSYS rather than omitting them, since some broken software
assumes they exist) seems to be the only conforming way to do this on
linux.
2012-11-11 15:38:04 -05:00
Rich Felker efd4d87aa4 clean up sloppy nested inclusion from pthread_impl.h
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).
2012-11-08 17:04:20 -05:00
Rich Felker 6a04d1b8c6 fix order of syscall args for microblaze clone syscall
with this commit, based on testing with patches to qemu which are not
yet upstream,
2012-10-19 00:27:03 -04:00
Rich Felker 1f485230df ensure microblaze __set_thread_area returns success
since it did not set the return-value register, the caller could
wrongly interpret this as failure.
2012-10-18 22:01:24 -04:00
Rich Felker ef2f595f74 fix microblaze asm relocations for shared libc
only @PLT relocations are considered functions for purposes of
-Bsymbolic-functions, so always use @PLT. it should not hurt in the
static-linked case.
2012-10-17 23:45:21 -04:00
Rich Felker 9ec4283b28 add support for TLS variant I, presently needed for arm and mips
despite documentation that makes it sound a lot different, the only
ABI-constraint difference between TLS variants II and I seems to be
that variant II stores the initial TLS segment immediately below the
thread pointer (i.e. the thread pointer points to the end of it) and
variant I stores the initial TLS segment above the thread pointer,
requiring the thread descriptor to be stored below. the actual value
stored in the thread pointer register also tends to have per-arch
random offsets applied to it for silly micro-optimization purposes.

with these changes applied, TLS should be basically working on all
supported archs except microblaze. I'm still working on getting the
necessary information and a working toolchain that can build TLS
binaries for microblaze, but in theory, static-linked programs with
TLS and dynamic-linked programs where only the main executable uses
TLS should already work on microblaze.

alignment constraints have not yet been heavily tested, so it's
possible that this code does not always align TLS segments correctly
on archs that need TLS variant I.
2012-10-15 18:51:53 -04:00
Rich Felker 42c36f957d fix overlap of thread stacks with thread tls segments 2012-10-14 21:10:44 -04:00
Rich Felker 0a96a37f06 clean up and refactor program initialization
the code in __libc_start_main is now responsible for parsing auxv,
rather than duplicating the parsing all over the place. this should
shave off a few cycles and some code size. __init_libc is left as an
external-linkage function despite the fact that it could be static, to
prevent it from being inlined and permanently wasting stack space when
main is called.

a few other minor changes are included, like eliminating per-thread
ssp canaries (they were likely broken when combined with certain
dlopen usages, and completely unnecessary) and some other unnecessary
checks. since this code gets linked into every program, it should be
as small and simple as possible.
2012-10-07 21:43:46 -04:00
Rich Felker dcd6037150 support for TLS in dynamic-loaded (dlopen) modules
unlike other implementations, this one reserves memory for new TLS in
all pre-existing threads at dlopen-time, and dlopen will fail with no
resources consumed and no new libraries loaded if memory is not
available. memory is not immediately distributed to running threads;
that would be too complex and too costly. instead, assurances are made
that threads needing the new TLS can obtain it in an async-signal-safe
way from a buffer belonging to the dynamic linker/new module (via
atomic fetch-and-add based allocator).

I've re-appropriated the lock that was previously used for __synccall
(synchronizing set*id() syscalls between threads) as a general
pthread_create lock. it's a "backwards" rwlock where the "read"
operation is safe atomic modification of the live thread count, which
multiple threads can perform at the same time, and the "write"
operation is making sure the count does not increase during an
operation that depends on it remaining bounded (__synccall or dlopen).
in static-linked programs that don't use __synccall, this lock is a
no-op and has no cost.
2012-10-05 11:51:50 -04:00
Rich Felker 9b153c043e beginnings of full TLS support in shared libraries
this code will not work yet because the necessary relocations are not
supported, and cannot be supported without some internal changes to
how relocation processing works (coming soon).
2012-10-04 21:01:56 -04:00
Rich Felker 8431d7972f TLS (GNU/C11 thread-local storage) support for static-linked programs
the design for TLS in dynamic-linked programs is mostly complete too,
but I have not yet implemented it. cost is nonzero but still low for
programs which do not use TLS and/or do not use threads (a few hundred
bytes of new code, plus dependency on memcpy). i believe it can be
made smaller at some point by merging __init_tls and __init_security
into __libc_start_main and avoiding duplicate auxv-parsing code.

at the same time, I've also slightly changed the logic pthread_create
uses to allocate guard pages to ensure that guard pages are not
counted towards commit charge.
2012-10-04 16:35:46 -04:00
Rich Felker e44849f5cf protect sem_open against cancellation
also fix one minor bug: failure to free the early-reserved slot when
the semaphore later found to already be mapped.
2012-09-30 19:44:45 -04:00
Rich Felker bf258341b7 overhaul sem_open
this function was overly complicated and not even obviously correct.
avoid using openat/linkat just like in shm_open, and instead expand
pathname using code shared with shm_open. remove bogus (and dangerous,
with priorities) use of spinlocks.

this commit also heavily streamlines the code and ensures there are no
failure cases that can happen after a new semaphore has been created
in the filesystem, since that case is unreportable.
2012-09-30 19:35:40 -04:00
Rich Felker 3d8d90c5cc sem_open should make process-shared semaphores
this did not matter because we don't yet treat process-shared special.
when private futex support is added, however, it will matter.
2012-09-29 16:49:32 -04:00
Rich Felker 39f296a95b use O_CLOEXEC to open semaphore files in sem_open 2012-09-29 16:48:52 -04:00
Rich Felker c983e6415a fix some indention-with-spaces that crept in 2012-09-29 01:14:07 -04:00
Rich Felker 8c0a3d9e5c microblaze port
based on initial work by rdp, with heavy modifications. some features
including threads are untested because qemu app-level emulation seems
to be broken and I do not have a proper system image for testing.
2012-09-29 01:05:31 -04:00
Rich Felker e0ea44cb76 fix arm clone syscall bug (no effect unless app uses clone)
the code to exit the new thread/process after the start function
returns was mixed up in its syscall convention.
2012-09-27 18:56:10 -04:00
Rich Felker 881868382a update mips cancellation-point syscall asm with 7-arg and r25 fixes
these fixes were already made to the normal syscall asm but not the
cancellation point version.
2012-09-15 02:24:12 -04:00
Rich Felker be48e22b42 fix mips syscall_cp_asm code (saved register usage) 2012-09-09 00:59:30 -04:00
Rich Felker 0c05bd3a9c further use of _Noreturn, for non-plain-C functions
note that POSIX does not specify these functions as _Noreturn, because
POSIX is aligned with C99, not the new C11 standard. when POSIX is
eventually updated to C11, it will almost surely give these functions
the _Noreturn attribute. for now, the actual _Noreturn keyword is not
used anyway when compiling with a c99 compiler, which is what POSIX
requires; the GCC __attribute__ is used instead if it's available,
however.

in a few places, I've added infinite for loops at the end of _Noreturn
functions to silence compiler warnings. presumably
__buildin_unreachable could achieve the same thing, but it would only
work on newer GCCs and would not be portable. the loops should have
near-zero code size cost anyway.

like the previous _Noreturn commit, this one is based on patches
contributed by philomath.
2012-09-06 23:34:10 -04:00
Rich Felker 400c5e5c83 use restrict everywhere it's required by c99 and/or posix 2008
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.
2012-09-06 22:44:55 -04:00
Rich Felker da8d0fc4fa fix extremely rare but dangerous race condition in robust mutexes
if new shared mappings of files/devices/shared memory can be made
between the time a robust mutex is unlocked and its subsequent removal
from the pending slot in the robustlist header, the kernel can
inadvertently corrupt data in the newly-mapped pages when the process
terminates. i am fixing the bug by using the same global vm lock
mechanism that was used to fix the race condition with unmapping
barriers after pthread_barrier_wait returns.
2012-08-17 17:13:53 -04:00
Rich Felker 2f437040e7 fix (hopefully) all hard-coded 8's for kernel sigset_t size
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.
2012-08-09 22:52:13 -04:00