|
Помоги найти мой косяк. Функция Sleep перестает работать. |
|
|
|
 |
Ответов
|
Mar 9 2011, 17:48
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 22-12-05
Пользователь №: 12 556

|
Ну вроде похоже отловил причину. Не знаю как назвать, багом или особенностью Scm.
Что получилось. Процесс с более высоким приоритетом прерывает ожидающий сообщений из канала. ConsumersProcessMap соответственно указывает, что процесс в ожидании. Далее Высокоприоритетный начинает отрабатываться достаточно долго, чтоб в ожидающем процессе произошел таймаут ожидания сообщения из канала. Ожидающий процесс встал в готовность. Теперь высокоприоритетный доходит до конца выполнения и кладет элемент в очередь сообщений, естественно не обнуляя ConsumersProcessMap (ожидающий процесс уже готов!). Далее управление передается ожидавшему процессу и тут идет проверка на наличие элемента в очереди (а он уже есть!), соответственно ConsumersProcessMap тоже в этом месте не нулится, как при вылетании по таймауту.
Итого: Теперь если процесс попытается встать на ожидание какого-то другого события и в очередь сообщений придет элемент получится пролет ожидание этого события.
Вот думаю, что делать. Добавить чистку ConsumersProcessMap во время POP из канала? Но получится идеологически неверно влезать в сорцы оси. Но и в своем коде менять принцип не хочется.
|
|
|
|
|
Mar 10 2011, 07:45
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(BAT @ Mar 9 2011, 23:48)  Процесс с более высоким приоритетом прерывает ожидающий сообщений из канала. ConsumersProcessMap соответственно указывает, что процесс в ожидании. Не понял, как может быть прерван процесс, ожидающий сообщения - ведь и так находится в неактивном состоянии. Цитата(BAT @ Mar 9 2011, 23:48)  Вот думаю, что делать. Добавить чистку ConsumersProcessMap во время POP из канала? Но получится идеологически неверно влезать в сорцы оси. Но и в своем коде менять принцип не хочется. Там в коде в функции pop есть такой фрагмент: Код if(pool.get_count()) { p->Timeout = 0; item = pool.pop(); CheckWaiters(ProducersProcessMap); return true; } if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired { // or by OS::ForceWakeUpProcess() p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess() ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map return false; } Попробуйте поменять эти два if'а местами - должно порешать вашу проблему. Сейчас готовится новая версия, там как раз такой порядок проверки условий. Заодно узнаем, правильное это решение или нет.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 10 2011, 09:35
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 22-12-05
Пользователь №: 12 556

|
Цитата(dxp @ Mar 10 2011, 10:45)  Не понял, как может быть прерван процесс, ожидающий сообщения - ведь и так находится в неактивном состоянии. Согласен, не так выразился. Не прерывает, а просто просыпается более высокоприоритетный. По поводу поменять местами. В принципе проблему решит. Правда сначала вывалится с ошибкой таймаута (практически он таки имел место), а при повторном входе сразу выйдет с уже нужным сообщением. Наверное так логичнее, чем сделал. Просто в лоб поставил чистку ConsumersProcessMap. Код if(pool.get_count()) { p->Timeout = 0; item = pool.pop(); CheckWaiters(ProducersProcessMap); ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map return true; } При таком варианте вываливания с таймаутом не будет, что наверное не совсем корректно.
|
|
|
|
|
Mar 10 2011, 11:51
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(BAT @ Mar 10 2011, 15:35)  По поводу поменять местами. В принципе проблему решит. Правда сначала вывалится с ошибкой таймаута (практически он таки имел место), а при повторном входе сразу выйдет с уже нужным сообщением. Наверное так логичнее, чем сделал. Мы спорили промеж себя, как правильнее - фиксировать ли таймаут, если к моменту получения ожидающим процессом управления таймаут уже истёк. С одной стороны ведь событие произошло - почему бы его сразу не обработать, зачем ждать следующего входа в ожидание события; с другой - заявленный таймаут реально истёк, а уж по какой причине - дело второе. На практике особой разницы (в обозримых случаях) как-то не очень видно - всё это на уровне "гонок". Главное, чтобы событие не терялось. Было бы интересно узнать, решит ли на практике перестановка местами условий вашу проблему. Вопрос не праздный - в готовящейся версии логика именно такая. Если вам не сложно проверить, попробуйте, пожалуйста.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
Сообщений в этой теме
a9d Помоги найти мой косяк. Функция Sleep перестает работать. Dec 26 2010, 22:00 dxp Цитата(a9d @ Dec 27 2010, 07:00) Вот не м... Dec 27 2010, 03:04 a9d Все нашел.
Для меж процессорного обмена использов... Dec 30 2010, 16:56 BAT Добавлю свой вопрос сюда. Есть ощущение, что из то... Mar 6 2011, 11:24 Rusoil Как понимаю функция ожидания эвента должна возвращ... Mar 6 2011, 14:13 BAT В данном случаи возврат идет с результатом false, ... Mar 6 2011, 17:12 BAT Нащупал точку проблемы. Похоже я неправильно испол... Mar 9 2011, 15:54    501-q Цитата(dxp @ Mar 10 2011, 17:51) Мы спори... May 17 2011, 09:59     dxp Цитата(501-q @ May 17 2011, 16:59) Н... May 17 2011, 12:28 BAT Поменял местами. Как и ожидалось, проблема ушла.
... Mar 10 2011, 12:03 dxp Цитата(BAT @ Mar 10 2011, 18:03) Поменял ... Mar 10 2011, 12:36
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|