Re: recursive spinlocks. Shoot.

Peter T. Breuer (ptb@it.uc3m.es)
Mon, 19 May 2003 14:48:55 +0200 (MET DST)


"A month of sundays ago Davide Libenzi wrote:"
> On Mon, 19 May 2003, Peter T. Breuer wrote:
>
> > No. This is not true. Imagine two threads, timed as follows ...
> >
> > .
> > .
> > .
> > .
> > if ((snl)->uniq == current) {
> > atomic_inc(&(snl)->count); .
> > } else { .
> > spin_lock(&(snl)->lock); .
> > atomic_inc(&(snl)->count); .
> > (snl)->uniq = current; <-> if ((snl)->uniq == current) {
> > atomic_inc(&(snl)->count);
> > } else {
> > spin_lock(&(snl)->lock);
> > atomic_inc(&(snl)->count);
> > (snl)->uniq = current;
> >
> >
> > There you are. One hits the read exactly at the time the other does a
> > write. Bang.
>
> So, what's bang for you ? The second task (the one that reads "uniq")
> will either see "uniq" as NULL or as (task1)->current. And it'll go
> acquiring the lock, as expected. Check it again ...

Perhaps I should expand on my earlier answer ...

(1) while, with some luck, writing may be atomic on ia32 (and I'm not
sure it is, I'm only prepared to guarantee it for the lower bits, and I
really don't know about zeroing the carry and so on), I actually doubt
that reading is atomic, or we wouldn't need the atomic_read
construction!

(2) I'm not prepared to bet that one either sees the answer from
before the write was done, or the answer after it is done. I would
suspect that one can get anything, including an explosion or reading
of the works of tolstoy ...

(3) even if one gets either one or the other answer, one of them would
be the wrong answer, and you clearly intend the atomic_inc of the
counter to be done in the same atomic region as the setting to current,
which would be a programming hypothesis that is broken when the wrong
answer comes up.

Peter
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/