On 09/01, Peter Zijlstra wrote:
>
> >     ret = 0;
> >
> >     for (;;) {
> >             prepare_to_wait_exclusive(wq, &q->wait, mode);
> >
> >             if (test_bit(&q->key.bit_nr, &q->key.flag))
> >                     ret = action(&q->key, mode);
> >
> >             if (!test_and_set_bit(&q->key.bit_nr, &q->key.flag)) {
> >                     /* we got the lock anyway, ignore the signal */
> >                     ret = 0;
> >                     break;
> >             }
> >
> >             if (ret)
> >                     break;
> >     }
> >     finish_wait(wq, &q->wait);
> >
> >     return ret;
> >
> >
> > Would not that work too?
>
> Nope, because we need to do that finish_wait() before
> test_and_set_bit()..

Yes, I meant

        int __sched
        __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q,
                                wait_bit_action_f *action, unsigned mode)
        {
                int ret = 0;

                for (;;) {
                        prepare_to_wait_exclusive(wq, &q->wait, mode);
                        if (test_bit(q->key.bit_nr, q->key.flags))
                                ret = action(&q->key, mode);

                        finish_wait(wq, &q->wait);

                        if (!test_and_set_bit(q->key.bit_nr, q->key.flags))
                                return 0;
                        else if (ret)
                                return ret;

                }
        }

> Also the problem with doing finish_wait() unconditionally would be
> destroying the FIFO order. With a bit of bad luck you'd get starvation
> cases :/

OK, I didn't think about that, thanks.

Oleg.

Reply via email to