<div dir="ltr">Some fairly significant signal safety additions have been made to libc and pthreads in master.  Anyone upgrading please note that you will need to do a full world and kernel build.<div><br></div><div>The basis for this is that for a very long time we've had problems building a number of large packages, in particular lang/mono and lang/rust.  The builds would only succeed one time out of ten, or one time out of twenty, and just fail to complete the rest of the time.  After a lot of messing around we traced the failures down to signal safety issues in both libc (primarily the malloc subsystem), but also pthreads (primarily mutex recursions and deadlocks from signal handlers).</div><div><br></div><div>But not just these two applications.  Really any large, sophisticated application that tries to implement any sort of signal-based asynchronous garbage collection or other mechanism is stretching the limits and causing issues.  As these applications become more sophisticated they begin not only to trip over our library code, but their own code as well.  The result is that some applications are just aren't as robust as we'd like them to be.</div><div><br></div><div>The basic problem with doing signal-safety is that it normally eats at least two system calls, often in performance-critical code paths, as well as messes with signal masks which can interfere with the expectations of the application.  To solve the problem properly and be able to enable signal safety across every important function in libc and pthreads I have created another shared user/kernel memory mapping called 'lpmap', which is similar to the upmap and kpmap, but which is able to give us a per-thread interface.  lpmap is per-thread, upmap is per-process, and kpmap is system-wide.</div><div><br></div><div>With this new mechanism signal safety is as easy as incrementing and decrementing a variable in memory that the kernel also has access to and can use to prevent posts during critical section of code.  The signal safety now being tested in master uses this new mechanism.  Two new libc routines have been created to support it:</div><div><br></div><div><a href="https://leaf.dragonflybsd.org/cgi/web-man?command=sigblockall&section=ANY">https://leaf.dragonflybsd.org/cgi/web-man?command=sigblockall&section=ANY</a><br></div><div><br></div><div>The memory allocator and most internal mutex used by pthreads have been wrapped with this functionality.  We couldn't do this without the 'lpmap', it would just be too expensive otherwise.  Languages such as rust and mono are now far more reliable because of this, and we continue to test other applications.</div><div><br></div><div>The primary repo commits implementing this are shown below.  Note that there are also some follow-up stability and cleanup commits to these:</div><div><br></div><div><a href="https://gitweb.dragonflybsd.org/dragonfly.git/commit/721505dec240e78696660384d988da78813a33bd">https://gitweb.dragonflybsd.org/dragonfly.git/commit/721505dec240e78696660384d988da78813a33bd</a><br></div><div><br></div><div><a href="https://gitweb.dragonflybsd.org/dragonfly.git/commit/64b5a8a550c3c782ab04d04d63723691ac054ffc">https://gitweb.dragonflybsd.org/dragonfly.git/commit/64b5a8a550c3c782ab04d04d63723691ac054ffc</a><br></div><div><br></div><div>Master will see more commits in coming weeks wrapping more library code and/or replacing existing uses of sigprocmask() system calls (particularly in rtld) to improve performance.  sigblockall()/sigunblockall() is a much cleaner mechanism.</div><div><br></div><div>-Matt</div></div>