1. 27 4月, 2013 3 次提交
    • R
      use atomic decrement rather than cas in pthread_exit thread count · c3a6839c
      Rich Felker 提交于
      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.
      c3a6839c
    • R
      add comments on some of the pthread_exit logic · 6e531f99
      Rich Felker 提交于
      6e531f99
    • R
      always block signals in pthread_exit before decrementing thread count · 23f21c30
      Rich Felker 提交于
      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.
      23f21c30
  2. 06 4月, 2013 1 次提交
  3. 01 4月, 2013 1 次提交
    • R
      implement pthread_getattr_np · 14a835b3
      Rich Felker 提交于
      this function is mainly (purely?) for obtaining stack address
      information, but we also provide the detach state since it's easy to
      do anyway.
      14a835b3
  4. 27 3月, 2013 1 次提交
    • R
      remove __SYSCALL_SSLEN arch macro in favor of using public _NSIG · ccc7b4c3
      Rich Felker 提交于
      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.
      ccc7b4c3
  5. 02 2月, 2013 3 次提交
    • R
      fix stale locks left behind when pthread_create fails · 72768ea9
      Rich Felker 提交于
      this bug seems to have been around a long time.
      72768ea9
    • R
      if pthread_create fails, it must not attempt mmap if there is no mapping · 077549e0
      Rich Felker 提交于
      this bug was introduced when support for application-provided stacks
      was originally added.
      077549e0
    • R
      pthread stack treatment overhaul for application-provided stacks, etc. · d5142642
      Rich Felker 提交于
      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.
      d5142642
  6. 12 11月, 2012 1 次提交
    • R
      add support for thread scheduling (POSIX TPS option) · 1e21e78b
      Rich Felker 提交于
      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.
      1e21e78b
  7. 09 11月, 2012 1 次提交
    • R
      clean up sloppy nested inclusion from pthread_impl.h · efd4d87a
      Rich Felker 提交于
      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).
      efd4d87a
  8. 16 10月, 2012 1 次提交
    • R
      add support for TLS variant I, presently needed for arm and mips · 9ec4283b
      Rich Felker 提交于
      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.
      9ec4283b
  9. 15 10月, 2012 1 次提交
  10. 08 10月, 2012 1 次提交
    • R
      clean up and refactor program initialization · 0a96a37f
      Rich Felker 提交于
      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.
      0a96a37f
  11. 05 10月, 2012 2 次提交
    • R
      support for TLS in dynamic-loaded (dlopen) modules · dcd60371
      Rich Felker 提交于
      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.
      dcd60371
    • R
      TLS (GNU/C11 thread-local storage) support for static-linked programs · 8431d797
      Rich Felker 提交于
      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.
      8431d797
  12. 07 9月, 2012 2 次提交
    • R
      further use of _Noreturn, for non-plain-C functions · 0c05bd3a
      Rich Felker 提交于
      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.
      0c05bd3a
    • R
      use restrict everywhere it's required by c99 and/or posix 2008 · 400c5e5c
      Rich Felker 提交于
      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.
      400c5e5c
  13. 10 8月, 2012 1 次提交
    • R
      fix (hopefully) all hard-coded 8's for kernel sigset_t size · 2f437040
      Rich Felker 提交于
      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.
      2f437040
  14. 12 7月, 2012 2 次提交
    • R
      fix several locks that weren't updated right for new futex-based __lock · bbbe87e3
      Rich Felker 提交于
      these could have caused memory corruption due to invalid accesses to
      the next field. all should be fixed now; I found the errors with fgrep
      -r '__lock(&', which is bogus since the argument should be an array.
      bbbe87e3
    • R
      fix potential race condition in detached threads · 92f8396b
      Rich Felker 提交于
      after the thread unmaps its own stack/thread structure, the kernel,
      performing child tid clear and futex wake, could clobber a new mapping
      made at the same location as the just-removed thread's tid field.
      disable kernel clearing of child tid to prevent this.
      92f8396b
  15. 10 6月, 2012 1 次提交
    • R
      add pthread_attr_setstack interface (and get) · 819006a8
      Rich Felker 提交于
      i originally omitted these (optional, per POSIX) interfaces because i
      considered them backwards implementation details. however, someone
      later brought to my attention a fairly legitimate use case: allocating
      thread stacks in memory that's setup for sharing and/or fast transfer
      between CPU and GPU so that the thread can move data to a GPU directly
      from automatic-storage buffers without having to go through additional
      buffer copies.
      
      perhaps there are other situations in which these interfaces are
      useful too.
      819006a8
  16. 03 6月, 2012 1 次提交
  17. 24 5月, 2012 1 次提交
  18. 05 5月, 2012 1 次提交
    • R
      make pthread stacks non-executable · 7e4d7946
      Rich Felker 提交于
      this change is necessary or pthread_create will always fail on
      security-hardened kernels. i considered first trying to make the stack
      executable and simply retrying without execute permissions when the
      first try fails, but (1) this would incur a serious performance
      penalty on hardened systems, and (2) having the stack be executable is
      just a bad idea from a security standpoint.
      
      if there is real-world "GNU C" code that uses nested functions with
      threads, and it can't be fixed, we'll have to consider other ways of
      solving the problem, but for now this seems like the best fix.
      7e4d7946
  19. 04 5月, 2012 1 次提交
    • R
      overhaul SSP support to use a real canary · 58aa5f45
      Rich Felker 提交于
      pthread structure has been adjusted to match the glibc/GCC abi for
      where the canary is stored on i386 and x86_64. it will need variants
      for other archs to provide the added security of the canary's entropy,
      but even without that it still works as well as the old "minimal" ssp
      support. eventually such changes will be made anyway, since they are
      also needed for GCC/C11 thread-local storage support (not yet
      implemented).
      
      care is taken not to attempt initializing the thread pointer unless
      the program actually uses SSP (by reference to __stack_chk_fail).
      58aa5f45
  20. 28 2月, 2012 1 次提交
  21. 10 2月, 2012 1 次提交
    • R
      small fix for new pthread cleanup stuff · 2230218c
      Rich Felker 提交于
      even if pthread_create/exit code is not linked, run flag needs to be
      checked and cleanup function potentially run on pop. thus, move the
      code to the module that's always linked when pthread_cleanup_push/pop
      is used.
      2230218c
  22. 09 2月, 2012 1 次提交
    • R
      replace bad cancellation cleanup abi with a sane one · afc35d5e
      Rich Felker 提交于
      the old abi was intended to duplicate glibc's abi at the expense of
      being ugly and slow, but it turns out glib was not even using that abi
      except on non-gcc-compatible compilers (which it doesn't even support)
      and was instead using an exceptions-in-c/unwind-based approach whose
      abi we could not duplicate anyway without nasty dwarf2/unwind
      integration.
      
      the new abi is copied from a very old glibc abi, which seems to still
      be supported/present in current glibc. it avoids all unwinding,
      whether by sjlj or exceptions, and merely maintains a linked list of
      cleanup functions to be called from the context of pthread_exit. i've
      made some care to ensure that longjmp out of a cleanup function should
      work, even though it is not required to.
      
      this change breaks abi compatibility with programs which were using
      pthread cancellation, which is unfortunate, but that's why i'm making
      the change now rather than later. considering that most pthread
      features have not been usable until recently anyway, i don't see it as
      a major issue at this point.
      afc35d5e
  23. 28 9月, 2011 1 次提交
  24. 18 9月, 2011 1 次提交
    • R
      overhaul clone syscall wrapping · 3f72cdac
      Rich Felker 提交于
      several things are changed. first, i have removed the old __uniclone
      function signature and replaced it with the "standard" linux
      __clone/clone signature. this was necessary to expose clone to
      applications anyway, and it makes it easier to port __clone to new
      archs, since it's now testable independently of pthread_create.
      
      secondly, i have removed all references to the ugly ldt descriptor
      structure (i386 only) from the c code and pthread structure. in places
      where it is needed, it is now created on the stack just when it's
      needed, in assembly code. thus, the i386 __clone function takes the
      desired thread pointer as its argument, rather than an ldt descriptor
      pointer, just like on all other sane archs. this should not affect
      applications since there is really no way an application can use clone
      with threads/tls in a way that doesn't horribly conflict with and
      clobber the underlying implementation's use. applications are expected
      to use clone only for creating actual processes, possibly with new
      namespace features and whatnot.
      3f72cdac
  25. 12 8月, 2011 1 次提交
    • R
      pthread and synccall cleanup, new __synccall_wait op · 407d9330
      Rich Felker 提交于
      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.
      407d9330
  26. 04 8月, 2011 3 次提交
    • R
      further debloat cancellation handlers · 5f37fc13
      Rich Felker 提交于
      cleanup push and pop are also no-ops if pthread_exit is not reachable.
      this can make a big difference for library code which needs to protect
      itself against cancellation, but which is unlikely to actually be used
      in programs with threads/cancellation.
      5f37fc13
    • R
      missed detail in cancellation bloat fix · 56385dd5
      Rich Felker 提交于
      56385dd5
    • R
      fix static linking dependency bloat with cancellation · 730bee72
      Rich Felker 提交于
      previously, pthread_cleanup_push/pop were pulling in all of
      pthread_create due to dependency on the __pthread_unwind_next
      function. this was not needed, as cancellation cleanup handlers can
      never be called unless pthread_exit or pthread_cancel is reachable.
      730bee72
  27. 30 7月, 2011 2 次提交
    • R
      add proper fuxed-based locking for stdio · dba68bf9
      Rich Felker 提交于
      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.
      dba68bf9
    • R
      new attempt at making set*id() safe and robust · acb04806
      Rich Felker 提交于
      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...
      acb04806
  28. 14 6月, 2011 3 次提交
    • R
      fix race condition in pthread_kill · 7779dbd2
      Rich Felker 提交于
      if thread id was reused by the kernel between the time pthread_kill
      read it from the userspace pthread_t object and the time of the tgkill
      syscall, a signal could be sent to the wrong thread. the tgkill
      syscall was supposed to prevent this race (versus the old tkill
      syscall) but it can't; it can only help in the case where the tid is
      reused in a different process, but not when the tid is reused in the
      same process.
      
      the only solution i can see is an extra lock to prevent threads from
      exiting while another thread is trying to pthread_kill them. it should
      be very very cheap in the non-contended case.
      7779dbd2
    • R
      run dtors before taking the exit-lock in pthread exit · f58c8a0f
      Rich Felker 提交于
      previously a long-running dtor could cause pthread_detach to block.
      f58c8a0f
    • R
      minor locking optimizations · 6232b96f
      Rich Felker 提交于
      6232b96f