about summary refs log tree commit diff
path: root/src/internal/libc.h
Commit message (Collapse)AuthorAgeFilesLines
* restore lock-skipping for processes that return to single-threaded stateRich Felker2020-05-221-0/+1
| | | | | | | | | the design used here relies on the barrier provided by the first lock operation after the process returns to single-threaded state to synchronize with actions by the last thread that exited. by storing the intent to change modes in the same object used to detect whether locking is needed, it's possible to avoid an extra (possibly costly) memory load after the lock is taken.
* cut down size of some libc struct membersRich Felker2020-05-221-3/+3
| | | | these are all flags that can be single-byte values.
* don't use libc.threads_minus_1 as relaxed atomic for skipping locksRich Felker2020-05-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | after all but the last thread exits, the next thread to observe libc.threads_minus_1==0 and conclude that it can skip locking fails to synchronize with any changes to memory that were made by the last-exiting thread. this can produce data races. on some archs, at least x86, memory synchronization is unlikely to be a problem; however, with the inline locks in malloc, skipping the lock also eliminated the compiler barrier, and caused code that needed to re-check chunk in-use bits after obtaining the lock to reuse a stale value, possibly from before the process became single-threaded. this in turn produced corruption of the heap state. some uses of libc.threads_minus_1 remain, especially for allocation of new TLS in the dynamic linker; otherwise, it could be removed entirely. it's made non-volatile to reflect that the remaining accesses are only made under lock on the thread list. instead of libc.threads_minus_1, libc.threaded is now used for skipping locks. the difference is that libc.threaded is permanently true once an additional thread has been created. this will produce some performance regression in processes that are mostly single-threaded but occasionally creating threads. in the future it may be possible to bring back the full lock-skipping, but more care needs to be taken to produce a safe design.
* remove volatile qualification from category pointers in __locale_structRich Felker2018-10-201-1/+1
| | | | | | | | | | commit 63c188ec42e76ff768e81f6b65b11c68fc43351e missed making this change when switching from atomics to locking for modification of the global locale, leaving access to locale structures unnecessarily burdened with the restrictions of volatile. the volatile qualification was originally added in commit 56fbaa3bbe73f12af2bfbbcf2adb196e6f9fe264.
* split internal lock API out of libc.h, creating lock.hRich Felker2018-09-121-6/+0
| | | | | | | | | this further reduces the number of source files which need to include libc.h and thereby be potentially exposed to libc global state and internals. this will also facilitate further improvements like adding an inline fast-path, if we want to do so later.
* move misplaced __fork_handler declarationRich Felker2018-09-121-0/+1
| | | | | | | | pthread_atfork.c does not actually include pthread_impl.h and has no reason to, so it wasn't getting the declaration. move it to libc.h which is already included by both fork.c and pthread_atfork.c. this makes more sense anyway since the function has little to do with pthreads anyway aside from the name.
* remove spurious inclusion of libc.h for LFS64 ABI aliasesRich Felker2018-09-121-6/+0
| | | | | | the LFS64 macro was not self-documenting and barely saved any characters. simply use weak_alias directly so that it's clear what's being done, and doesn't depend on a header to provide a strange macro.
* reduce spurious inclusion of libc.hRich Felker2018-09-121-2/+0
| | | | | | | | | | | | | | | | | | | | | libc.h was intended to be a header for access to global libc state and related interfaces, but ended up included all over the place because it was the way to get the weak_alias macro. most of the inclusions removed here are places where weak_alias was needed. a few were recently introduced for hidden. some go all the way back to when libc.h defined CANCELPT_BEGIN and _END, and all (wrongly implemented) cancellation points had to include it. remaining spurious users are mostly callers of the LOCK/UNLOCK macros and files that use the LFS64 macro to define the awful *64 aliases. in a few places, new inclusion of libc.h is added because several internal headers no longer implicitly include libc.h. declarations for __lockfile and __unlockfile are moved from libc.h to stdio_impl.h so that the latter does not need libc.h. putting them in libc.h made no sense at all, since the macros in stdio_impl.h are needed to use them correctly anyway.
* declare and make hidden additional internal init/exit symbolsRich Felker2018-09-121-0/+4
|
* apply hidden visibility to various remaining internal interfacesRich Felker2018-09-121-5/+5
|
* overhaul internally-public declarations using wrapper headersRich Felker2018-09-121-9/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | commits leading up to this one have moved the vast majority of libc-internal interface declarations to appropriate internal headers, allowing them to be type-checked and setting the stage to limit their visibility. the ones that have not yet been moved are mostly namespace-protected aliases for standard/public interfaces, which exist to facilitate implementing plain C functions in terms of POSIX functionality, or C or POSIX functionality in terms of extensions that are not standardized. some don't quite fit this description, but are "internally public" interfacs between subsystems of libc. rather than create a number of newly-named headers to declare these functions, and having to add explicit include directives for them to every source file where they're needed, I have introduced a method of wrapping the corresponding public headers. parallel to the public headers in $(srcdir)/include, we now have wrappers in $(srcdir)/src/include that come earlier in the include path order. they include the public header they're wrapping, then add declarations for namespace-protected versions of the same interfaces and any "internally public" interfaces for the subsystem they correspond to. along these lines, the wrapper for features.h is now responsible for the definition of the hidden, weak, and weak_alias macros. this means source files will no longer need to include any special headers to access these features. over time, it is my expectation that the scope of what is "internally public" will expand, reducing the number of source files which need to include *_impl.h and related headers down to those which are actually implementing the corresponding subsystems, not just using them.
* improve machinery for ldso to report libc versionRich Felker2018-09-121-0/+2
| | | | | | | | eliminate gratuitous glue function for reporting the version, which was probably leftover from the old dynamic linker design which lacked a clear barrier for when/how it could access global data. put the declaration for the data object that replaces it in libc.h where it can be type checked.
* define and use internal macros for hidden visibility, weak refsRich Felker2018-09-051-13/+10
| | | | | | | | | this cleans up what had become widespread direct inline use of "GNU C" style attributes directly in the source, and lowers the barrier to increased use of hidden visibility, which will be useful to recovering some of the efficiency lost when the protected visibility hack was dropped in commit dc2f368e565c37728b0d620380b849c3a1ddd78f, especially on archs where the PLT ABI is costly.
* unify static and dynamic linked implementations of thread-local storageRich Felker2015-11-121-1/+8
| | | | | | | | | | | | | | | | | this both allows removal of some of the main remaining uses of the SHARED macro and clears one obstacle to static-linked dlopen support, which may be added at some point in the future. specialized single-TLS-module versions of __copy_tls and __reset_tls are removed and replaced with code adapted from their dynamic-linked versions, capable of operating on a whole chain of TLS modules, and use of the dynamic linker's DSO chain (which contains large struct dso objects) by these functions is replaced with a new chain of struct tls_module objects containing only the information needed for implementing TLS. this may also yield some performance benefit initializing TLS for a new thread when a large number of modules without TLS have been loaded, since since there is no need to walk structures for modules without TLS.
* refactor stdio open file list handling, move it out of global libc structRich Felker2015-06-161-2/+0
| | | | | | | | | | | | | functions which open in-memory FILE stream variants all shared a tail with __fdopen, adding the FILE structure to stdio's open file list. replacing this common tail with a function call reduces code size and duplication of logic. the list is also partially encapsulated now. function signatures were chosen to facilitate tail call optimization and reduce the need for additional accessor functions. with these changes, static linked programs that do not use stdio no longer have an open file list at all.
* overhaul locale internals to treat categories roughly uniformlyRich Felker2015-05-271-3/+1
| | | | | | | | | | | | | | | | | | | | previously, LC_MESSAGES was treated specially as the only category which could be set to a locale name without a definition file, in order to facilitate gettext message translations when no libc locale was available. LC_NUMERIC was completely un-settable, and LC_CTYPE stored a flag intended to be used for a possible future byte-based C locale, instead of storing a __locale_map pointer like the other categories use. this patch changes all categories to be represented by pointers to __locale_map structures, and allows locale names without definition files to be treated as valid locales with trivial definition when used in any category. outwardly visible functional changes should be minor, limited mainly to the strings read back from setlocale and the way gettext handles translations in categories other than LC_MESSAGES. various internal refactoring has also been performed, and improvements in const correctness have been made.
* eliminate costly tricks to avoid TLS access for current locale stateRich Felker2015-05-161-2/+0
| | | | | | | | | | | | | | | the code being removed used atomics to track whether any threads might be using a locale other than the current global locale, and whether any threads might have abstract 8-bit (non-UTF-8) LC_CTYPE active, a feature which was never committed (still pending). the motivations were to support early execution prior to setup of the thread pointer, to partially support systems (ancient kernels) where thread pointer setup is not possible, and to avoid high performance cost on archs where accessing the thread pointer may be very slow. since commit 19a1fe670acb3ab9ead0fe31859ca7d4fe40dd54, the thread pointer is always available, so these hacks are no longer needed. removing them greatly simplifies the affected code.
* fix inconsistent visibility for __hwcap and __sysinfo symbolsRich Felker2015-04-221-2/+3
| | | | | these are used as hidden by asm files (and such use is the whole reason they exist), but their actual definitions were not hidden.
* remove cruft for libc struct accessor function and broken visibilityRich Felker2015-04-221-14/+0
| | | | | | | | | these were hacks to work around toolchains that could not properly optimize PIC accesses based on visibility and would generate GOT lookups even for hidden data, which broke the old dynamic linker. since commit f3ddd173806fd5c60b3f034528ca24542aecc5b9 it no longer matters; the dynamic linker does not assume accessibility of this data until stage 3.
* remove remnants of support for running in no-thread-pointer modeRich Felker2015-04-131-2/+1
| | | | | | | | | | | | | since 1.1.0, musl has nominally required a thread pointer to be setup. most of the remaining code that was checking for its availability was doing so for the sake of being usable by the dynamic linker. as of commit 71f099cb7db821c51d8f39dfac622c61e54d794c, this is no longer necessary; the thread pointer is now valid before any libc code (outside of dynamic linker bootstrap functions) runs. this commit essentially concludes "phase 3" of the "transition path for removing lazy init of thread pointer" project that began during the 1.1.0 release cycle.
* make all objects used with atomic operations volatileRich Felker2015-03-031-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | the memory model we use internally for atomics permits plain loads of values which may be subject to concurrent modification without requiring that a special load function be used. since a compiler is free to make transformations that alter the number of loads or the way in which loads are performed, the compiler is theoretically free to break this usage. the most obvious concern is with atomic cas constructs: something of the form tmp=*p;a_cas(p,tmp,f(tmp)); could be transformed to a_cas(p,*p,f(*p)); where the latter is intended to show multiple loads of *p whose resulting values might fail to be equal; this would break the atomicity of the whole operation. but even more fundamental breakage is possible. with the changes being made now, objects that may be modified by atomics are modeled as volatile, and the atomic operations performed on them by other threads are modeled as asynchronous stores by hardware which happens to be acting on the request of another thread. such modeling of course does not itself address memory synchronization between cores/cpus, but that aspect was already handled. this all seems less than ideal, but it's the best we can do without mandating a C11 compiler and using the C11 model for atomics. in the case of pthread_once_t, the ABI type of the underlying object is not volatile-qualified. so we are assuming that accessing the object through a volatile-qualified lvalue via casts yields volatile access semantics. the language of the C standard is somewhat unclear on this matter, but this is an assumption the linux kernel also makes, and seems to be the correct interpretation of the standard.
* implement locale file loading and state for remaining locale categoriesRich Felker2014-07-241-0/+3
| | | | | | | | there is still no code which actually uses the loaded locale files, so the main observable effect of this commit is that calls to setlocale store and give back the names of the selected locales for the remaining categories (LC_TIME, LC_COLLATE, LC_MONETARY) if a locale file by the requested name could be loaded.
* add locale frameworkRich Felker2014-07-021-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | this commit adds non-stub implementations of setlocale, duplocale, newlocale, and uselocale, along with the data structures and minimal code needed for representing the active locale on a per-thread basis and optimizing the common case where thread-local locale settings are not in use. at this point, the data structures only contain what is necessary to represent LC_CTYPE (a single flag) and LC_MESSAGES (a name for use in finding message translation files). representation for the other categories will be added later; the expectation is that a single pointer will suffice for each. for LC_CTYPE, the strings "C" and "POSIX" are treated as special; any other string is accepted and treated as "C.UTF-8". for other categories, any string is accepted after being truncated to a maximum supported length (currently 15 bytes). for LC_MESSAGES, the name is kept regardless of whether libc itself can use such a message translation locale, since applications using catgets or gettext should be able to use message locales libc is not aware of. for other categories, names which are not successfully loaded as locales (which, at present, means all names) are treated as aliases for "C". setlocale never fails. locale settings are not yet used anywhere, so this commit should have no visible effects except for the contents of the string returned by setlocale.
* always initialize thread pointer at program startRich Felker2014-03-241-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | this is the first step in an overhaul aimed at greatly simplifying and optimizing everything dealing with thread-local state. previously, the thread pointer was initialized lazily on first access, or at program startup if stack protector was in use, or at certain random places where inconsistent state could be reached if it were not initialized early. while believed to be fully correct, the logic was fragile and non-obvious. in the first phase of the thread pointer overhaul, support is retained (and in some cases improved) for systems/situation where loading the thread pointer fails, e.g. old kernels. some notes on specific changes: - the confusing use of libc.main_thread as an indicator that the thread pointer is initialized is eliminated in favor of an explicit has_thread_pointer predicate. - sigaction no longer needs to ensure that the thread pointer is initialized before installing a signal handler (this was needed to prevent a situation where the signal handler caused the thread pointer to be initialized and the subsequent sigreturn cleared it again) but it still needs to ensure that implementation-internal thread-related signals are not blocked. - pthread tsd initialization for the main thread is deferred in a new manner to minimize bloat in the static-linked __init_tp code. - pthread_setcancelstate no longer needs special handling for the situation before the thread pointer is initialized. it simply fails on systems that cannot support a thread pointer, which are non-conforming anyway. - pthread_cleanup_push/pop now check for missing thread pointer and nop themselves out in this case, so stdio no longer needs to avoid the cancellable path when the thread pointer is not available. a number of cases remain where certain interfaces may crash if the system does not support a thread pointer. at this point, these should be limited to pthread interfaces, and the number of such cases should be fewer than before.
* fix potential deadlock bug in libc-internal locking logicRich Felker2013-09-201-2/+2
| | | | | | | | | | | | | | | | | | | | if a multithreaded program became non-multithreaded (i.e. all other threads exited) while one thread held an internal lock, the remaining thread would fail to release the lock. the the program then became multithreaded again at a later time, any further attempts to obtain the lock would deadlock permanently. the underlying cause is that the value of libc.threads_minus_1 at unlock time might not match the value at lock time. one solution would be returning a flag to the caller indicating whether the lock was taken and needs to be unlocked, but there is a simpler solution: using the lock itself as such a flag. note that this flag is not needed anyway for correctness; if the lock is not held, the unlock code is harmless. however, the memory synchronization properties associated with a_store are costly on some archs, so it's best to avoid executing the unlock code when it is unnecessary.
* support configurable page size on mips, powerpc and microblazeSzabolcs Nagy2013-09-151-0/+6
| | | | | | | | | | | | | | | | PAGE_SIZE was hardcoded to 4096, which is historically what most systems use, but on several archs it is a kernel config parameter, user space can only know it at execution time from the aux vector. PAGE_SIZE and PAGESIZE are not defined on archs where page size is a runtime parameter, applications should use sysconf(_SC_PAGE_SIZE) to query it. Internally libc code defines PAGE_SIZE to libc.page_size, which is set to aux[AT_PAGESZ] in __init_libc and early in __dynlink as well. (Note that libc.page_size can be accessed without GOT, ie. before relocations are done) Some fpathconf settings are hardcoded to 4096, these should be actually queried from the filesystem using statfs.
* add support for init/fini array in main program, and greatly simplifyRich Felker2013-07-211-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | modern (4.7.x and later) gcc uses init/fini arrays, rather than the legacy _init/_fini function pasting and crtbegin/crtend ctors/dtors system, on most or all archs. some archs had already switched a long time ago. without following this change, global ctors/dtors will cease to work under musl when building with new gcc versions. the most surprising part of this patch is that it actually reduces the size of the init code, for both static and shared libc. this is achieved by (1) unifying the handling main program and shared libraries in the dynamic linker, and (2) eliminating the glibc-inspired rube goldberg machine for passing around init and fini function pointers. to clarify, some background: the function signature for __libc_start_main was based on glibc, as part of the original goal of being able to run some glibc-linked binaries. it worked by having the crt1 code, which is linked into every application, static or dynamic, obtain and pass pointers to the init and fini functions, which __libc_start_main is then responsible for using and recording for later use, as necessary. however, in neither the static-linked nor dynamic-linked case do we actually need crt1.o's help. with dynamic linking, all the pointers are available in the _DYNAMIC block. with static linking, it's safe to simply access the _init/_fini and __init_array_start, etc. symbols directly. obviously changing the __libc_start_main function signature in an incompatible way would break both old musl-linked programs and glibc-linked programs, so let's not do that. instead, the function can just ignore the information it doesn't need. new archs need not even provide the useless args in their versions of crt1.o. existing archs should continue to provide it as long as there is an interest in having newly-linked applications be able to run on old versions of musl; at some point in the future, this support can be removed.
* consistently use the internal name __environ for environRich Felker2013-02-171-1/+0
| | | | | | | | | | | patch by Jens Gustedt. previously, the intended policy was to use __environ in code that must conform to the ISO C namespace requirements, and environ elsewhere. this policy was not followed in practice anyway, making things confusing. on top of that, Jens reported that certain combinations of link-time optimization options were breaking with the inconsistent references; this seems to be a compiler or linker bug, but having it go away is a nice side effect of the changes made here.
* fix trailing whitespace issues that crept in here and thereRich Felker2012-12-071-1/+1
|
* use explicit visibility to optimize a few hot-path function callsRich Felker2012-10-251-4/+4
| | | | | | | | | | | | | | | | | | | | | | on x86 and some other archs, functions which make function calls which might go through a PLT incur a significant overhead cost loading the GOT register prior to making the call. this load is utterly useless in musl, since all calls are bound at library-creation time using -Bsymbolic-functions, but the compiler has no way of knowing this, and attempts to set the default visibility to protected have failed due to bugs in GCC and binutils. this commit simply manually assigns hidden/protected visibility, as appropriate, to a few internal-use-only functions which have many callers, or which have callers that are hot paths like getc/putc. it shaves about 5k off the i386 libc.so with -Os. many of the improvements are in syscall wrappers, where the benefit is just size and performance improvement is unmeasurable noise amid the syscall overhead. however, stdio may be measurably faster. if in the future there are toolchains that can do the same thing globally without introducing linking bugs, it might be worth considering removing these workarounds.
* workaround broken hidden-visibility handling in pccRich Felker2012-10-131-1/+1
| | | | | | | | | | | | | with this change, pcc-built musl libc.so seems to work correctly. the problem is that pcc generates GOT lookups for external-linkage symbols even if they are hidden, rather than using GOT-relative addressing. the entire reason we're using hidden visibility on the __libc object is to make it accessible prior to relocations -- not to mention inexpensive to access. unfortunately, the workaround makes it even more expensive on pcc. when the pcc issue is fixed, an appropriate version test should be added so new pcc can use the much more efficient variant.
* support for TLS in dynamic-loaded (dlopen) modulesRich Felker2012-10-051-1/+1
| | | | | | | | | | | | | | | | | | | | | 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.
* TLS (GNU/C11 thread-local storage) support for static-linked programsRich Felker2012-10-041-0/+1
| | | | | | | | | | | | | 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.
* save AT_HWCAP from auxv for subsequent use in machine-specific codeRich Felker2012-07-271-0/+1
| | | | | | | it's expected that this will be needed/useful only in asm, so I've given it its own symbol that can be addressed in pc-relative ways from asm rather than adding a field in the __libc structure which would require hard-coding the offset wherever it's used.
* enable LARGEFILE64 aliasesRich Felker2012-05-311-2/+1
| | | | | | | | these will NOT be used when compiling with -D_LARGEFILE64_SOURCE on musl; instead, they exist in the hopes of eventually being able to run some glibc-linked apps with musl sitting in place of glibc. also remove the (apparently incorrect) fcntl alias.
* remove everything related to forkallRich Felker2012-05-221-1/+0
| | | | | | | | | | i made a best attempt, but the intended semantics of this function are fundamentally contradictory. there is no consistent way to handle ownership of locks when forking a multi-threaded process. the code could have worked by accident for programs that only used normal mutexes and nothing else (since they don't actually store or care about their owner), but that's about it. broken-by-design interfaces that aren't even in glibc (only solaris) don't belong in musl.
* ditch the priority inheritance locks; use malloc's version of lockRich Felker2012-04-241-1/+1
| | | | | | | | | | | | | | | | | | | i did some testing trying to switch malloc to use the new internal lock with priority inheritance, and my malloc contention test got 20-100 times slower. if priority inheritance futexes are this slow, it's simply too high a price to pay for avoiding priority inversion. maybe we can consider them somewhere down the road once the kernel folks get their act together on this (and perferably don't link it to glibc's inefficient lock API)... as such, i've switch __lock to use malloc's implementation of lightweight locks, and updated all the users of the code to use an array with a waiter count for their locks. this should give optimal performance in the vast majority of cases, and it's simple. malloc is still using its own internal copy of the lock code because it seems to yield measurably better performance with -O3 when it's inlined (20% or more difference in the contention stress test).
* new internal locking primitive; drop spinlocksRich Felker2012-04-241-1/+2
| | | | | | we use priority inheritance futexes if possible so that the library cannot hit internal priority inversion deadlocks in the presence of realtime priority scheduling (full support to be added later).
* new attempt at working around the gcc 3 visibility bugRich Felker2012-02-241-0/+3
| | | | | since gcc is failing to generate the necessary ".hidden" directive in the output asm, generate it explicitly with an __asm__ statement...
* cleanup and work around visibility bug in gcc 3 that affects x86_64Rich Felker2012-02-231-5/+10
| | | | | | | | | | | | | | in gcc 3, the visibility attribute must be placed on both the declaration and on the definition. if it's omitted from the definition, the compiler fails to emit the ".hidden" directive in the assembly, and the linker will either generate textrels (if supported, such as on i386) or refuse to link (on targets where certain types of textrels are forbidden or impossible without further assumptions about memory layout, such as on x86_64). this patch also unifies the decision about when to use visibility into libc.h and makes the visibility in the utf-8 state machine tables based on libc.h rather than a duplicate test.
* security hardening: ensure suid programs have valid stdin/out/errRich Felker2011-08-231-2/+4
| | | | | | | | | | | this behavior (opening fds 0-2 for a suid program) is explicitly allowed (but not required) by POSIX to protect badly-written suid programs from clobbering files they later open. this commit does add some cost in startup code, but the availability of auxv and the security flag will be useful elsewhere in the future. in particular auxv is needed for static-linked vdso support, which is still waiting to be committed (sorry nik!)
* pthread and synccall cleanup, new __synccall_wait opRich Felker2011-08-121-0/+1
| | | | | | | | | fix up clone signature to match the actual behavior. the new __syncall_wait function allows a __synccall callback to wait for other threads to continue without returning, so that it can resume action after the caller finishes. this interface could be made significantly more general/powerful with minimal effort, but i'll wait to do that until it's actually useful for something.
* simplify multi-threaded errno, eliminate useless function pointerRich Felker2011-08-061-2/+1
|
* use weak aliases rather than function pointers to simplify some codeRich Felker2011-08-061-2/+0
|
* add proper fuxed-based locking for stdioRich Felker2011-07-301-1/+2
| | | | | | | | | | | | | | | | | | | | | | previously, stdio used spinlocks, which would be unacceptable if we ever add support for thread priorities, and which yielded pathologically bad performance if an application attempted to use flockfile on a key file as a major/primary locking mechanism. i had held off on making this change for fear that it would hurt performance in the non-threaded case, but actually support for recursive locking had already inflicted that cost. by having the internal locking functions store a flag indicating whether they need to perform unlocking, rather than using the actual recursive lock counter, i was able to combine the conditionals at unlock time, eliminating any additional cost, and also avoid a nasty corner case where a huge number of calls to ftrylockfile could cause deadlock later at the point of internal locking. this commit also fixes some issues with usage of pthread_self conflicting with __attribute__((const)) which resulted in crashes with some compiler versions/optimizations, mainly in flockfile prior to pthread_create.
* new attempt at making set*id() safe and robustRich Felker2011-07-291-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | changing credentials in a multi-threaded program is extremely difficult on linux because it requires synchronizing the change between all threads, which have their own thread-local credentials on the kernel side. this is further complicated by the fact that changing the real uid can fail due to exceeding RLIMIT_NPROC, making it possible that the syscall will succeed in some threads but fail in others. the old __rsyscall approach being replaced was robust in that it would report failure if any one thread failed, but in this case, the program would be left in an inconsistent state where individual threads might have different uid. (this was not as bad as glibc, which would sometimes even fail to report the failure entirely!) the new approach being committed refuses to change real user id when it cannot temporarily set the rlimit to infinity. this is completely POSIX conformant since POSIX does not require an implementation to allow real-user-id changes for non-privileged processes whatsoever. still, setting the real uid can fail due to memory allocation in the kernel, but this can only happen if there is not already a cached object for the target user. thus, we forcibly serialize the syscalls attempts, and fail the entire operation on the first failure. this *should* lead to an all-or-nothing success/failure result, but it's still fragile and highly dependent on kernel developers not breaking things worse than they're already broken. ideally linux will eventually add a CLONE_USERCRED flag that would give POSIX conformant credential changes without any hacks from userspace, and all of this code would become redundant and could be removed ~10 years down the line when everyone has abandoned the old broken kernels. i'm not holding my breath...
* fix minor bugs due to incorrect threaded-predicate semanticsRich Felker2011-04-201-0/+1
| | | | | | | | | | | | some functions that should have been testing whether pthread_self() had been called and initialized the thread pointer were instead testing whether pthread_create() had been called and actually made the program "threaded". while it's unlikely any mismatch would occur in real-world problems, this could have introduced subtle bugs. now, we store the address of the main thread's thread descriptor in the libc structure and use its presence as a flag that the thread register is initialized. note that after fork, the calling thread (not necessarily the original main thread) is the new main thread.
* clean up handling of thread/nothread mode, lockingRich Felker2011-04-171-4/+3
|
* optimize cancellation enable/disable codeRich Felker2011-04-171-0/+1
| | | | | | | | | | | | | | | | | | the goal is to be able to use pthread_setcancelstate internally in the implementation, whenever a function might want to use functions which are cancellation points but avoid becoming a cancellation point itself. i could have just used a separate internal function for temporarily inhibiting cancellation, but the solution in this commit is better because (1) it's one less implementation-specific detail in functions that need to use it, and (2) application code can also get the same benefit. previously, pthread_setcancelstate dependend on pthread_self, which would pull in unwanted thread setup overhead for non-threaded programs. now, it temporarily stores the state in the global libc struct if threads have not been initialized, and later moves it if needed. this way we can instead use __pthread_self, which has no dependencies and assumes that the thread register is already valid.
* overhaul pthread cancellationRich Felker2011-04-171-7/+1
| | | | | | | | | | | | | | | | | | | | | | this patch improves the correctness, simplicity, and size of cancellation-related code. modulo any small errors, it should now be completely conformant, safe, and resource-leak free. the notion of entering and exiting cancellation-point context has been completely eliminated and replaced with alternative syscall assembly code for cancellable syscalls. the assembly is responsible for setting up execution context information (stack pointer and address of the syscall instruction) which the cancellation signal handler can use to determine whether the interrupted code was in a cancellable state. these changes eliminate race conditions in the previous generation of cancellation handling code (whereby a cancellation request received just prior to the syscall would not be processed, leaving the syscall to block, potentially indefinitely), and remedy an issue where non-cancellable syscalls made from signal handlers became cancellable if the signal handler interrupted a cancellation point. x86_64 asm is untested and may need a second try to get it right.