Commits on Mar 1, 2009
  1. fix compilation on win32

    Gabor Melis committed Mar 1, 2009
Commits on Feb 24, 2009
  1. SUB-GC: don't observe deadlines

    Gabor Melis committed Feb 24, 2009
    - because the condition that's signalled can cause arbitrary code to
      run catching us with pants down
    - and we should not skip gc if it was triggerred
Commits on Feb 17, 2009
  1. x86 disassembler fixes.

    Alastair Bridgewater committed Feb 17, 2009
      Made operand-size-prefix bytes disassemble correctly, using the same
    approach used in the x86-64 backend (extra instruction formats for
    reading the prefix byte).
      Fixed movzx and movsx instructions to indicate the size of the source
    data when moving from memory.
      Added printers for cbw, cwde and cwd instructions.
Commits on Feb 16, 2009
  1. centralize scattered arch_os_get_context() calls

    Gabor Melis committed Feb 16, 2009
    ... to the six signal handlers trampolines. These are now the only
    places where void_context appears, the rest of the runtime uses
    Also, the &void_context+37 hack was removed. On Sparc/Linux the third
    parameter of SA_SIGINFO signal handlers is a pointer to sigcontext,
    which happens to be the same as &void_context+37 most of the time,
    I have tested two on Sparc/Linux boxes, one running 2.6.26 that
    randomly segfaulted compiling itself with, and another
    runnin 2.6.24 that worked fine before at that version.
    Thanks to Bruce O'Neel for the shell access.
  2. fix gencgc_handle_wp_violation on multicpu systems

    Gabor Melis committed Feb 16, 2009
    Acquire free_pages_lock around page_table accesses to be sure that the
    changes actually propagate to other CPUs and we don't end up losing in
    the else branch and also to prevent problems caused by the compiler or
    the processor reordering stuff.
  3. go through lisp_memory_fault_error on all platforms

    Gabor Melis committed Feb 16, 2009
    ... so that the corruption mechanism can kick in.

    Gabor Melis committed Feb 16, 2009
    ... instead of WITH-RECURSIVE-SPINLOCK because it's possible to
    deadlock due to lock ordering with sufficiently unlucky interrupts as
    demonstrated by test (:timer :parallel-unschedule) with low
    This affects hash tables and some pcl locks.
    Also, use WITH-RECURSIVE-MUTEX for packages.
    Not a spinlock becuase it can be held for a long time and not a system
    lock (i.e. with WITHOUT-INTERRUPTS) because conflicts are signalled
    while holding the lock which I think this warrants a FIXME.
  5. detect binding and alien stack exhaustion

    Gabor Melis committed Feb 16, 2009
    Alien stack exhaustion machinery only works on x86oids.
  6. x86/x86-64 unithread: use the allocated alien stack

    Gabor Melis committed Feb 16, 2009
    ... in struct thread and not the original control stack that we switch
    away from in call_into_lisp_first_time.
  7. signals internals doc

    Gabor Melis committed Feb 16, 2009
  8. OOAO restoring fp control word

    Gabor Melis committed Feb 16, 2009
    Do it in all signal handlers, no matter what, on platforms that
    require it.
  9. restore errno in signal handlers

    Gabor Melis committed Feb 16, 2009
  10. fix futex_wait deadlines when interrupted

    Gabor Melis committed Feb 16, 2009
    When the syscall returned with EINTR futex_wait called again with the
    same timeout. Now it lets Lisp recalculate the relative timeout from
    the deadline.
  11. INTERRUPT-THREAD and timer improvements

    Gabor Melis committed Feb 16, 2009
    The main thing accomplished by this commit is that it's finally
    possible to use INTERRUPT-THREAD and TIMERS sanely:
    - there is a per thread interruption queue, interruption are executed
      in order of arrival
    - the interruption has to explicitly enable interrupts with
      WITH-INTERRUPTS if needed. In the absence of WITH-INTERRUPTS the
      interruption itself is not interrupted and running out of stack is
      not a problem.
    - timers have an improved repeat mechanism
    Implementation notes:
    - INTERRUPT-THREAD is implemented on all platforms and builds (that
      is, even without :SB-THREAD) by sending a signal to the current
      thread (or process without thread). This allows us to hook into the
      normal, interrupt deferral mechanism without having to commit OAOO
      violations on the Lisp side. And it makes threaded, non-threaded
      builds closer, hopefully easing testing.
    - SIG_INTERRUPT_THREAD is SIGPIPE on all platforms. SIGPIPE is not
      used in SBCL for its original purpose, instead it's for signalling a
      thread that it should look at its interruption queue. The handler
      (RUN_INTERRUPTION) just returns if there is nothing to do so it's
      safe to receive spurious SIGPIPEs coming from the kernel.
    - IN-INTERRUPTION does not unblock deferrables anymore, but arranges
      for them to be unblocked when interrupts are enabled (see
    - Thread interruption run wrapped in a (WITHOUT-INTERRUPTS
    - Repeating timers reschedule themselves when they finished to the
      current expiry time + repeat interval even if that's in the past.
      Hence, a timer's schedule does not get shifted if it takes a long
      time to run. If it takes more time than the repeat interval then it
      may catch up on later invokations.
      ...)) even in run in a new thread.
    - Enable previously failing tests.
    - Add more tests.
    - Automatically unschedule repeating timers if they take up all the
  12. alpha interrupt context fixes

    Gabor Melis committed Feb 16, 2009
    - interrupt contexts pointers are 64 bit
    - add padding to DEFINE-PRIMITIVE-OBJECT THREAD, because the C
      compiler aligns interrupt_contexts on a double word boundary
  13. make os_thread 0 on unithread builds

    Gabor Melis committed Feb 16, 2009
    ... because storing the pid there (two places really, thread.os_thread
    and THREAD-OS-THREAD) complicates SB-POSIX:FORK, and makes a simple
    fork() lose.
  14. only call pthread_kill with valid thread ids

    Gabor Melis committed Feb 16, 2009
    ... else it segfaults (at least on Linux). Fixes sporadic "Unhandled
    memory fault" running timer, INTERRUPT-THREAD heavy code. And block
    signals while calling pthread_kill because it is not async signal
  15. fix JOIN-THREAD

    Gabor Melis committed Feb 16, 2009
    If the thread has not returned normally signal the error when not
    holding the mutex anymore. Disable interrupt for the duration of
    holding the mutex. Fix test.
  16. thread start/stop fixes

    Gabor Melis committed Feb 16, 2009
    - disable interrupts during create_thread
      ... to protect against signals (async unwinds, reentrancy, ...)
      during malloc, pthread code and to make the pinning of
      INITIAL-FUNCTION effective. Also add checks to
    - make-thread: assert gc enabled (to prevent deadlocks)
    - block blockables while holding LOCK_CREATE_THREAD lock
    - make dying threads safe from interrupts
  17. fix maybe_gc

    Gabor Melis committed Feb 16, 2009
  18. block deferrables when gc pending in PA

    Gabor Melis committed Feb 16, 2009
    Consider this:
      alloc and set pseudo_atomic_interrupted and GC_PENDING
      if (get_pseudo_atomic_interrupted())
    If an async interrupt happens and unwinds between
    clear_pseudo_atomic_atomic and gc() we have lost a gc trigger until
    the next alloc. Same with SIG_STOP_FOR_GC instead of alloc.
    This patch addresses the above problem by blocking deferrables when a
    gc is requested in a pseudo atomic section. On exit from the protected
    section there is no race because no async unwinding interrupts can
  19. unblock signals on low level errors

    Gabor Melis committed Feb 16, 2009
    Low level errors (control stack exhausted, memory fault) may trigger
    at inconvenient times such as in signal handlers still running with
    deferrables blocked. Due to the condition handling mechanism this
    leads to executing user code at unsafe places and the image may very
    well become corrupted. To allow continuing anyway with fingers crossed
    to diagnose the problem, deferrable and/or gc signals are unblocked
    before arranging for returning to the Lisp function that signals the
    appropriate condition. Before that is done, however, a warning is
    fprintf'ed to stderr to that this important piece of information is
    not lost in some generic condition handler (or in a interrupt handler
    async unwinding before anyone gets a chance to handle the condition)
    which makes diagnosis of subsequent problems very hard.
    This was brought to light by the checks added in the previous commit.
  20. check that gc signals are unblocked

    Gabor Melis committed Feb 16, 2009
    ... when alloc() is called and when calling into Lisp.
  21. gc trigger improvements

    Gabor Melis committed Feb 16, 2009
    - Make sure that gc never runs user code (after gc hooks and
      finalizers) if interrupts are disabled and they cannot be enabled
      (i.e. *ALLOW-WITH-INTERRUPTS* is NIL).
    - clean up maybe_gc: we know that in the interrupted context gc
      signals are unblocked (see "check that gc signals are unblocked"
      commit) so it's safe to simply enable them and call SUB-GC
  22. protect against recursive gcs

    Gabor Melis committed Feb 16, 2009
    ... while holding the *already-in-gc* lock instead of allowing gc to
    trigger and then punting.
  23. improvements to WITHOUT-GCING

    Gabor Melis committed Feb 16, 2009
    - implement it with only one UNWIND-PROTECT (about 30% faster)
    - add *IN-WITHOUT-GCING*
    - in maybe_defer_handler defer interrupts if we are in the racy part
      of WITHOUT-GCING, that is with interrupts enabled, gc allowed but
      still *IN-WITHOUT-GCING*
    - check more invariants
  24. axe GC-{ON,OFF}

    Gabor Melis committed Feb 16, 2009
    ... because they are broken, nobody uses them (?), and complicated to
    - There is no way to safely allow gc in a WITHOUT-GCING without making
    it entirely useless (nothing like the interrupt protocol with
    - WITHOUT-GCING implies WITHOUT-INTERRUPTS because interrupts running
    with gc disabled may lead to deadlocks (see internals manual on lock
    ordering and WITHOUT-GCING) or running out of memory. To adhere to
    this contract GC-{ON,OFF} would need to enable/disable interrupts by
    setting *INTERRUPTS-ENABLED*, comlicated business for little gain.
  25. INTERRUPT-THREAD without RT signals

    Gabor Melis committed Feb 16, 2009
    All non-win32 platforms converted to use normal signals
    Remove mention of RT signals from the internals manual.
  26. thread state visibility and synchronization

    Gabor Melis committed Feb 16, 2009
    C does not guarantee that changes made to a volatile variable in one
    thread are visibile to other threads. Use locking primitives (that
    have memory barrier semantics) for that purpose.
    Thus, all_threads need not be volatile: it's always accessed while
    holding all_threads_lock. Thread state does not need volatile either,
    as signal a handlers don't change it (save for sig_stop_for_gc_handler
    but that sets it restores its value). But visibility issues can arise
    and potentially deadlock in stop_the_world, so the thread state is
    given a lock. And to reduce busy looping while waiting for the state
    to change to STATE_SUSPENDED a condition variable is added as well.
    Also convert sig_stop_for_gc_handler to use
    wait_for_thread_state_change which frees up SIG_RESUME_FROM_GC. I
    think this also guarantees that the changes made by the gc are visible
    in other threads on non x86 platforms (on x86 it's already the case).
    With these changes threads.impure.lisp runs 10% a faster in real time.
  27. always use SIG_RESUME_FROM_GC

    Gabor Melis committed Feb 16, 2009
    The other mechanism relied on real time signals which made it freeze
    when the sysystem wide real time signal queue got full on Linux. A
    full queue spells trouble for other processes using rt signals.
    All platforms are changed to use SIGUSR1 and SIGUSR2 for
    Check that SIG_RESUME_FROM_GC is never signalled without a
    corresponding sigwait.
  28. codify interrupt handling invariants

    Gabor Melis committed Feb 16, 2009
  29. less interrupt handling leftovers

    Gabor Melis committed Feb 16, 2009
    - less clear_pseudo_atomic_interrupted
      Remove it from the beginning of the protected sections in the
      runtime to match what we do in Lisp.
    - less resetting of signal mask
      Don't call reset-signal-mask from the toplevel, I don't think it's
      useful anymore and quite likely it was never more than duct tape.
      Even when unmasking of signals is called for (in
      INVOKE-INTERRUPTION), only unblock the deferrable ones: gc signals
      are unblocked in Lisp anyway.
    - removed unneeded sigemptyset on pending mask
    - move MIPS SIGTRAP workaround to the runtime
  30. sig_stop_for_gc_handler looks at GC_INHIBIT first

    Gabor Melis committed Feb 16, 2009
    ... else we'd trap on every single pseudo atomic until gc is finally