Commit [5abf3b] Maximize Restore History

fix bogus deadlocks from interrupts and GCs

lp#807475

Going in despite the freeze since this is a regression that can
semi-randomly break correct code. *ouch*

Thanks to Bart Bortta and #sbcl for the analysis.

Problem 1:

T1 holds L1

T2 is waiting for L1

T2 is interrupted, interrupt handler grabs L2

T1 starts waiting on L2

Prior to this patch, when GET-MUTEX in T2's interrupt handler grabbed
L2 is marked T2 as still waiting for L1 -- which is not true until
the interrupt handler returns.

Problem 2:

T1 holds L1

T2 is waiting for L1

GC is triggered in T2 inside GET-MUTEX

T2 grabs *ALREADY-IN-GC* lock

GC is triggered in T1, T1 tries to get *ALREADY-IN-GC* lock.

Prior to this patch, when T1 detects a bogus deadlock as T2 has
been marked as waiting for L1 -- which is not true until the GC is
finished and normal execution resumes.

Problem 3:

T1 holds L1

T2 is waiting for L1

GC is triggered in T2 inside GET-MUTEX

T2 grabs lock L2 due to a finalizer or an after-gc-hook

GC is triggered in T1

T1 tries to grab L2 due to a finalizer, etc.

Same as problem 2, but with a user-lock and POST-GC instead of
*ALREADY-IN-GC* and SUB-GC.

This patch fixes the issue by saving, clearing, and restoring
the waiting-for mark in

1) interrupt handlers

2) SUB-GC

3) POST-GC

Nikodemus Siivola Nikodemus Siivola 2011-08-15

changed src/code/gc.lisp
changed src/code/target-signal.lisp
changed src/code/target-thread.lisp
changed src/code/thread.lisp
changed tests/threads.impure.lisp
changed NEWS
src/code/gc.lisp Diff Switch to side-by-side view
Loading...
src/code/target-signal.lisp Diff Switch to side-by-side view
Loading...
src/code/target-thread.lisp Diff Switch to side-by-side view
Loading...
src/code/thread.lisp Diff Switch to side-by-side view
Loading...
tests/threads.impure.lisp Diff Switch to side-by-side view
Loading...
NEWS Diff Switch to side-by-side view
Loading...