Цитата(Сергей Борщ @ Nov 11 2010, 14:07)

Нет, флаг чистится всегда если есть хоть один ждущий процесс. Будятся все ждущие процессы и чистится флаг.
Должен быть очищен. В момент выхода из wait() он может быть уже снова взведен, но в момент пробуждения ждущего процесса он очищается.
Что-то я не пойму.
Вот код из ветки
https://scmrtos.svn.sourceforge.net/svnroot...os/trunk/Common, 268 revision:
Код
bool OS::TEventFlag::Wait(TTimeout timeout)
{
TCritSect cs;
if(Value) // if flag already signaled
{
Value = efOff; // clear flag
return true;
}
else
{
TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
p->Timeout = timeout;
TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
SetPrioTag(ProcessMap, PrioTag); // put current process to the wait map
ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
Kernel.Scheduler();
p->Timeout = 0;
if( !(ProcessMap & PrioTag) ) // if waked up by signal() or signal_ISR()
return true;
ClrPrioTag(ProcessMap, PrioTag); // otherwise waked up by timeout or by
return false; // OS::ForceWakeUpProcess(), remove process from the wait map
}
}
В ветке else я не вижу очистки флага. Да и вопрос возник-то из практики: думал, что флаг сбрасывается всегда, написал некий код, запускаю - то работает, то нет. Оказалось, что флаг иногда остается взведенным.
Цитата
Идея простая: когда флаг сигналится, это означает, что произошло событие (которое ожидает один [или несколько] процесс[ов]). При этом все ожидающие (процессы) будут переведены из спячки в активное состояние, а управление получат в соответствии со своими приоритетами. Флаг сбрасывает первый из ожидающих (самый приоритетный), но это не отменяет того, что остальные процессы, которые успели встать на ожидание флага до возникновения события, тоже станут активными - т.е. дождавшимися события, которое они хотели.
Да в общем и целом, конечно понятно. А как разбуженные узнают, кто из них сейчас самый приоритетный ИЗ ОЖИДАЮЩИХ? Ведь самый-самый мог сейчас события и не ждать. Но мой вопрос даже не в том "почему сделано так, а не эдак", а как имея данный механизм корректно вручную из процесса флаг сбрасывать? И почему не сделали сброс внутри wait()? Ведь сам факт побудки процесса с результатом true уже говорит о том, что событие произошло! Зачем мне после выхода еще анализировать что-то и сбрасывать флаг?
Конечно, в самом простом случае, когда один сигналит, а другой ждет, можно тупо всегда после wait() делать сброс, но тогда небольшой оверхед получим.
Посмотрел внимательнее и понял, что флаг не взводится если его уже ждут процессы. А у меня он видимо все-же не "оставался взведенным", а уже сигналил повторно. Думаю, вопрос закрыт...