From: Nikodemus S. <nik...@ra...> - 2006-09-24 11:26:45
|
Gábor Melis <me...@re...> writes: >> http://zaval.org/resources/library/butenhof1.html > Wow, that's long. Certainly longer than my attention span. > > I may have written a paragraph on interrupt safety and locks in the > internal manuals. The short example I keep in my head is: > > (defun remove-x (something) > (with-mutex (*x-lock*) > (setq *x* (delete something *x*))) > > If an interrupt hits while holding *x-lock* and calls remove-x we > deadlock after printing a warning about recursive lock attempt (see > get-mutex). > > One way around it is to wrap the with-mutex in without-interrupts and > suffer style point deduction. > > One could also think that with-recursive lock is better because it > doesn't deadlock in the above case but it doesn't produce correct > results: one of the things to be removed is likely still in *x*. Quite. I think the main points in the article are: 1. If you think you need recursive locks your locking scheme is not well thought out. 2. Ok, sometimes you do want recursive locks, but you're still pissing away your chances of concurrency. 3. You should not be able to release a lock which you don't hold. 4. Debugging-mutexes which go an extra mile to detect funny stuff are a good idea. The way reason about these in SBCL context looks something like this: 1&2. If you are holding a mutex you should give it up before being interrupted, and since asynch unwinds are bad a non-recursive mutex should always be accompanied by without-interrupts. ...or you need a recursive lock and need to be fully reentrant. 3. RELEASE-MUTEX is nasty as it is currently written. OTOH, given an interactive environment, NUKE-MUTEX --or whatever-- can be handly. 4. Doing decent-effort deadlock detection in GET-MUTEX would not be particularly hard, just slow. Similarly, a slower mutex variant could enforce a gc-inhibit policy. Cheers, -- Nikodemus Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs." |