| RScheme call trace | 24. June 2007 |
How to print the call stack. - Some helpful tips from Donovan. | |
This reached me in private mail, though we had better sent it via some mailing list for archiving. Von: Donovan Kolbly
An: Jörg F. Wittenberger
Betreff: Re: mutex owner
Datum: Fri, 22 Jun 2007 06:40:05 -0500 (13:40 CEST)
Jörg "F. Wittenberger" <Joerg.Wittenberger@softeyes.net> writes:
> Am Mittwoch, den 20.06.2007, 13:47 -0500 schrieb Donovan Kolbly:
>> Jörg "F. Wittenberger" <Joerg.Wittenberger@softeyes.net> writes:
> ...
>> > Can you confirm that my attempt to capture the real state of the mutex
>> > is correct. If so, do you see any chance that my code could be
>> > incorrect, or should this issue be counted as an rscheme bug?
>>
>> There is a minor race condition between the extraction of the owner
>> and the count. Ideally, you would do that within an atomic block.
>> I'd have to look at the AML to if `count' and `mutext-owner' are being
>> inlined.
>>
>> I forget what you said the apparent bug was... You have a thread
>> grabbing the lock twice -- what is the higher level constraint that
>> makes this nominally impossible?
>
> It's just not supposed to be the case and looking at the source, it
> *should* not. Hm, I said this so many times. ;-/
>
> Now I still can't see how whatever race condition between extraction of
> whatever values from the mutex would matter: either the current thread
> holds the lock (as the mutex-owner==current-thread is going to confirm),
> then it will not change owner not count between extraction and test or
> it does not hold the lock, then the test should fail. Hence no error
> raised.
>
> The only race condition I could see was, if mutex-owner where still set
> after mutex-unlock.
>
> Where is my blind spot?
Actually, I just wasn't thinking about the error-raising branch. I
was just looking at the extraction of the data.
I think you're right that *if* an error is raised *then* c must
accurately reflect the mutex count.
So... This is a little mysterious.
Have you tried figuring out where the calls are being made? Something
like this comes to mind if you're not using mutex-specific already:
(define mutex-lock-tested!
(let ((ml mutex-lock!))
(lambda (m)
(let ((cth (current-thread))
(o (mutex-owner m))
(c (count m)))
(if (eq? o cth)
(begin
(set! logcond logcond-full)
(with-output-to-file
"/tmp/remux.out"
(lambda ()
(format #t "thread ~a holds mutex ~s (~a) already" cth c m)
(format #t "-------ORIGINALLY----------\n")
(print (continuation->partial (mutex-specific m)))
(format #t "-------RELOCK----------\n")
(call-with-current-continuation
(lambda (cc)
(print (continuation->partial cc))))))
(error "thread ~a holds mutex ~s (~a) already" cth c m))
(begin
(ml m)
;; remember where we grabbed the lock...
(call-with-current-continuation
(lambda (cc)
(mutex-specific-set! m cc)))))))))
(define (ll->partial (llc <function>))
(gvec-ref (environment llc) 1))
(define (continuation->partial (cc <function>))
(ll->partial (gvec-ref (environment cc) 1)))
>
>> > (I just
>> > double checked: grep does not find redefinitions of mutex-lock! besides
>> > this one.)
>> >
>> > best regards
>> > /Jörg
>> >
>> > Am Mittwoch, den 20.06.2007, 10:25 +0200 schrieb Jörg F. Wittenberger:
>> >> the other day I wrote you about mutex-lock at count 1 while mutex-owner
>> >> == (current-thread). Recall: print on unwind -> fake count value.
>> >>
>> >> OK,
>> >>
>> >> (define mutex-lock-tested!
>> >> (let ((ml mutex-lock!))
>> >> (lambda (m)
>> >> (let ((cth (current-thread))
>> >> (o (mutex-owner m))
>> >> (c (count m)))
>> >> (if (eq? o cth)
>> >> (begin
>> >> (set! logcond logcond-full)
>> >> (error "thread ~a holds mutex ~s (~a) already" cth c m))
>> >> (ml m))))))
>> >>
>> >> (set! mutex-lock! mutex-lock-tested!)
>
>
>
--
Donovan
| |
Post replies via login host.