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

    - 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
    Gabor Melis committed Feb 24, 2009
Commits on Feb 17, 2009
  1. x86 disassembler fixes.

      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.
    Alastair Bridgewater committed Feb 17, 2009
Commits on Feb 16, 2009
  1. centralize scattered arch_os_get_context() calls

    ... 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.
    Gabor Melis committed Feb 16, 2009
  2. fix gencgc_handle_wp_violation on multicpu systems

    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.
    Gabor Melis committed Feb 16, 2009
  3. go through lisp_memory_fault_error on all platforms

    ... 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.
    Gabor Melis committed Feb 16, 2009
  5. detect binding and alien stack exhaustion

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

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

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

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

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

    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.
    Gabor Melis committed Feb 16, 2009
  11. INTERRUPT-THREAD and timer improvements

    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
    Gabor Melis committed Feb 16, 2009
  12. alpha interrupt context fixes

    - 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
    Gabor Melis committed Feb 16, 2009
  13. make os_thread 0 on unithread builds

    ... 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.
    Gabor Melis committed Feb 16, 2009
  14. only call pthread_kill with valid thread ids

    ... 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
    Gabor Melis committed Feb 16, 2009
  15. fix JOIN-THREAD

    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.
    Gabor Melis committed Feb 16, 2009
  16. thread start/stop fixes

    - 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
    Gabor Melis committed Feb 16, 2009
  17. fix maybe_gc

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

    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
    Gabor Melis committed Feb 16, 2009
  19. unblock signals on low level errors

    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.
    Gabor Melis committed Feb 16, 2009
  20. check that gc signals are unblocked

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

    - 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
    Gabor Melis committed Feb 16, 2009
  22. protect against recursive gcs

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

    - 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
    Gabor Melis committed Feb 16, 2009
  24. axe GC-{ON,OFF}

    ... 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.
    Gabor Melis committed Feb 16, 2009
  25. INTERRUPT-THREAD without RT signals

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

    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.
    Gabor Melis committed Feb 16, 2009
  27. always use SIG_RESUME_FROM_GC

    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.
    Gabor Melis committed Feb 16, 2009
  28. codify interrupt handling invariants

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

    - 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
    Gabor Melis committed Feb 16, 2009
  30. sig_stop_for_gc_handler looks at GC_INHIBIT first

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