=AlexD= (28.01.2008 08:45, просмотров: 167) ответил Cepгeй Бopщ на Вот, получилось такое, надо тестировать. Сможете проверить в своем проекте? На примере работает, как в жизни - не знаю. Надо бы еще придумать пример, который показывает все эти аспекты поведения.
Тааак... а если ДО того, как получит управление самая низкоприоритетная задача из ожидавших эвент, он будет выставлен снова?
Эта задача, получив управление его благополучно сбросит, и он будет потерян.
Как не оптимизирь, но от проверки в OS::TEventFlag::Signal(), ждёт ли ктото эвент не уйти.
Также нельзя сбрасывать глобальный флажок efOn после Kernel.Scheduler();
Итого, как я понимаю, вытанцовывается следующая картина:
bool OS::TEventFlag::Wait(TTimeout timeout)
{
TCritSect cs;
TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
if(ProcessMap & efOn) // if flag signalled alredy
{
ClrPrioTag(ProcessMap, efOn); // clear flag
return true;
}
else
{
TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
p->Timeout = timeout;
SetPrioTag(ProcessMap, PrioTag); // put current process to wait map
ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from ready map
Kernel.Scheduler();
p->Timeout = 0;
if( !(ProcessMap & PrioTag) ) // if waked-up by signal() or signal_ISR()
{
return true;
}
// otherwice waked-up by timeout or
// by OS::ForceWakeUpProcess()
ClrPrioTag(ProcessMap, PrioTag); // remove process from wait map
return false;
}
}
//------------------------------------------------------------------------------
void OS::TEventFlag::Signal()
{
TCritSect cs;
if (ProcessMap)
{
OS::Kernel.ReadyProcessMap |= ProcessMap; // place all waiting processes to ready map
ProcessMap = 0; // remove all processes from waiting map
}
else
{
ProcessMap = efOn; // set efOn bit
}
// to inform processes that waked-up by signal
Kernel.Scheduler();
}
Три кита на которых зиждется реклама: враньё, преувеличение, замалчивание. Новости СМИ - это политическая реклама.