Messages in this thread |  | | Date | Thu, 1 Feb 2007 00:30:42 +0300 | From | Oleg Nesterov <> | Subject | Re: [PATCH 3/7] barrier: a scalable synchonisation barrier |
| |
On 02/01, Oleg Nesterov wrote: > > +static inline void barrier_sync(struct barrier *b) > +{ > + might_sleep(); > + > + if (unlikely(atomic_read(&b->count))) { > + DEFINE_WAIT(wait); > + prepare_to_wait(&b->wait, &wait, TASK_UNINTERRUPTIBLE); > + while (atomic_read(&b->count)) > + schedule(); > + finish_wait(&b->wait, &wait); > + } > +} > > This should be open-coded wait_event(), but wrong! With the scenario above this > can hang forever! because the first wake_up removes the task from the &b->wait.
I am afraid I was not clear (as usual :). prepare_to_wait means autoremove_wake_function. So, if barrier_unlock() wakes up the caller of barrier_sync(), it will be removed from b->wait. If it goes to schedule() because another barrier_lock() incremented b->count, we can't wake it via __wake_up(&b->wait, ...).
Oleg.
- 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/
|  |