libc - Implement sigblockall() and sigunblockall()
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 12 Nov 2019 01:35:42 +0000 (17:35 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 12 Nov 2019 01:46:17 +0000 (17:46 -0800)
commit721505dec240e78696660384d988da78813a33bd
tree26ccf3a695abfb8b259bc6a3eb07c65385526755
parent64b5a8a550c3c782ab04d04d63723691ac054ffc
libc - Implement sigblockall() and sigunblockall()

* Signal safety is becoming a defacto requirement for most of libc and
  pthreads.  In particular, the memory allocator.  Given the chances of
  teaching tens of thousands of programmers about signal safety, and
  just making it work in libc and pthreads, only one of these two
  possibilities is actually realizable.

  In particular, high-level languages have become so complex, and some
  applications (chrome, firefox, etc) have become so complex, that the
  code is regularly tripping over signal safety issues.

  However, implementing signal safety with current mechanisms is extremely
  expensive due to the need for multiple system calls.  To whit,
  DragonFlyBSD now has a mechanism that does not require system calls
  in the critical path.

* Implement sigblockall() and sigunblockall().  These functions
  leverage the new /dev/lpmap per-thread shared page mechanism
  to provide a way to temporary block the dispatch of all maskable
  signals without having to make any system calls.

  These are extremely fast routines.

  - Reentrant / Recursable

  - Temporarily blocks any dispatch of a maskable asynchronous signal
    to the calling thread.  Other threads are not affected... this is
    a per-thread mechanism.

  - The last sigunblockall() will immediately dispatch any blocked
    signals.

  - The normal signal mask is not affected by these routines.

  - Does not block signals caused by synchronous traps.

  - The current recursion count is retained on [v]fork() to ease
    coding and to also allow signals to be temporarily blocked across a
    fork until the child process is ready to deal with them, if desired.

* Implement signal safety for most of pthreads.  All temporary internal
  mutexes are now wrapped with sigblockall() and sigunblockall().

* Implement signal safety for the malloc subsystem.  All functions
  are wrawpped with sigblockall() and sigunblockall().

  These implementations make lang/mono and lang/rust far more reliable
  than they were before.  Where 9 out of 10 builds used to fail, now
  they succeed.
18 files changed:
lib/libc/gen/_thread_init.c
lib/libc/include/libc_private.h
lib/libc/stdlib/Symbol.map
lib/libc/stdlib/nmalloc.c
lib/libc/upmap/Makefile.inc
lib/libc/upmap/Symbol.map
lib/libc/upmap/ukp_blocksigs.c [new file with mode: 0644]
lib/libc/upmap/upmap.c
lib/libc/upmap/upmap.h
lib/libstand/Makefile
lib/libthread_xu/thread/thr_create.c
lib/libthread_xu/thread/thr_init.c
lib/libthread_xu/thread/thr_mutex.c
lib/libthread_xu/thread/thr_private.h
lib/libthread_xu/thread/thr_pspinlock.c
lib/libthread_xu/thread/thr_spinlock.c
lib/libthread_xu/thread/thr_umtx.h
libexec/rtld-elf/rtld.c