реклама на сайте
подробности

 
 
> Помоги найти мой косяк. Функция Sleep перестает работать.
a9d
сообщение Dec 26 2010, 22:00
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



У меня есть в проекте ошибка. Но я ее не могу отловить, вылетает в разные моменты времени.
Проект показывать смысла нет. Кода дохрена и никто не поймет.

Контролер ATmega8A 16MHz. Всего два процесса.
В какой то момент времени перестает работать правильно функция Sleep(). Т.е Sleep(500) начинает работать как Sleep(1) . При этом ОС работает замечательно.

Вот не могу понять. Что приводит к такому дивному эффекту? Или как эту хрень отловить.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
BAT
сообщение Mar 9 2011, 17:48
Сообщение #2


Участник
*

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



Ну вроде похоже отловил причину. Не знаю как назвать, багом или особенностью Scm.

Что получилось.
Процесс с более высоким приоритетом прерывает ожидающий сообщений из канала. ConsumersProcessMap соответственно указывает, что процесс в ожидании. Далее Высокоприоритетный начинает отрабатываться достаточно долго, чтоб в ожидающем процессе произошел таймаут ожидания сообщения из канала. Ожидающий процесс встал в готовность. Теперь высокоприоритетный доходит до конца выполнения и кладет элемент в очередь сообщений, естественно не обнуляя ConsumersProcessMap (ожидающий процесс уже готов!). Далее управление передается ожидавшему процессу и тут идет проверка на наличие элемента в очереди (а он уже есть!), соответственно ConsumersProcessMap тоже в этом месте не нулится, как при вылетании по таймауту.

Итого:
Теперь если процесс попытается встать на ожидание какого-то другого события и в очередь сообщений придет элемент получится пролет ожидание этого события.

Вот думаю, что делать. Добавить чистку ConsumersProcessMap во время POP из канала? Но получится идеологически неверно влезать в сорцы оси. Но и в своем коде менять принцип не хочется.
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 10 2011, 07:45
Сообщение #3


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'а местами - должно порешать вашу проблему. Сейчас готовится новая версия, там как раз такой порядок проверки условий. Заодно узнаем, правильное это решение или нет. sm.gif


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
BAT
сообщение Mar 10 2011, 09:35
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 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;                                                                              
}


При таком варианте вываливания с таймаутом не будет, что наверное не совсем корректно.
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 10 2011, 11:51
Сообщение #5


Adept
******

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



Цитата(BAT @ Mar 10 2011, 15:35) *
По поводу поменять местами. В принципе проблему решит. Правда сначала вывалится с ошибкой таймаута (практически он таки имел место), а при повторном входе сразу выйдет с уже нужным сообщением. Наверное так логичнее, чем сделал.

Мы спорили промеж себя, как правильнее - фиксировать ли таймаут, если к моменту получения ожидающим процессом управления таймаут уже истёк. С одной стороны ведь событие произошло - почему бы его сразу не обработать, зачем ждать следующего входа в ожидание события; с другой - заявленный таймаут реально истёк, а уж по какой причине - дело второе. На практике особой разницы (в обозримых случаях) как-то не очень видно - всё это на уровне "гонок". Главное, чтобы событие не терялось.

Было бы интересно узнать, решит ли на практике перестановка местами условий вашу проблему. Вопрос не праздный - в готовящейся версии логика именно такая. Если вам не сложно проверить, попробуйте, пожалуйста.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
501-q
сообщение May 17 2011, 09:59
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 24-02-09
Из: Екатеринбург
Пользователь №: 45 296



Цитата(dxp @ Mar 10 2011, 17:51) *
Мы спорили промеж себя, как правильнее - фиксировать ли таймаут, если к моменту получения ожидающим процессом управления таймаут уже истёк. С одной стороны ведь событие произошло - почему бы его сразу не обработать, зачем ждать следующего входа в ожидание события; с другой - заявленный таймаут реально истёк, а уж по какой причине - дело второе. На практике особой разницы (в обозримых случаях) как-то не очень видно - всё это на уровне "гонок". Главное, чтобы событие не терялось.

Было бы интересно узнать, решит ли на практике перестановка местами условий вашу проблему. Вопрос не праздный - в готовящейся версии логика именно такая. Если вам не сложно проверить, попробуйте, пожалуйста.


Сначала был таймаут. Поэтому возвращать нужно "таймаут".

Например, окончание телеграммы в модбасе -- по таймату. Если пришёл байт после таймаута -- это уже следующая телеграмма.

Илья
Go to the top of the page
 
+Quote Post
dxp
сообщение May 17 2011, 12:28
Сообщение #7


Adept
******

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



Цитата(501-q @ May 17 2011, 16:59) *
Например, окончание телеграммы в модбасе -- по таймату. Если пришёл байт после таймаута -- это уже следующая телеграмма.

А если пришёл байт (т.е. он первым пришёл, до таймаута), но пока управление передавалось от источника этого события к его обработчику, произошёл таймаут. Как быть? Что считать результатом - событие или таймаут? sm.gif


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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
- - BAT   Поменял местами. Как и ожидалось, проблема ушла. ...   Mar 10 2011, 12:03
- - dxp   Цитата(BAT @ Mar 10 2011, 18:03) Поменял ...   Mar 10 2011, 12:36


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 18:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01447 секунд с 7
ELECTRONIX ©2004-2016