Перейти к содержанию
    

Удаление семафора "на лету"

Есть задача сделать программный перезапуск lwip при ошибках. Для этого в ассёртах выдаётся семафор, в который упёрта задача собственно выполняющая перезапуск. Все создаваемые треды, семафоры и очереди сохраняются в связных списках по ходу создания (в sys_arch.c в функция создания этих объектов вызов добавления их в списки)

Сначала вызывается удаление всех тредов:

struct s_netapp *netapp = netapp_root;
    netapp_root = NULL;
    while(netapp != NULL)
    {
        struct s_netapp *current = netapp;
        netapp = netapp->next;
        vTaskDelete(current->handle);
        vPortFree(current);
        current = NULL;
    }

Вроде всё проходит ОК.

Затем выход из треда с приличной задержкой чтобы дать возможность выполниться айдлу в котором происходит освобождение памяти. Сам тред в котором запущено удаление так же имеет приоритет айдла.

Затем удаление семафоров:

struct s_semaphr *semphr = semaphr_root;
    semaphr_root = NULL;
    while(semphr != NULL)
    {
        printf("semaphore delete... %lu\n", semphr->sema);
        struct s_semaphr *current = semphr;
        semphr = semphr->next;
        vSemaphoreDelete(current->sema);
        vPortFree(current);
        current = NULL;
        printf("ok, semphr = %lu\n", semphr);
    }

И тут всё виснет после удаления 6 штук:

semaphore delete... 268462400

ok, semphr = 268462640

semaphore delete... 268462544

ok, semphr = 268462784

semaphore delete... 268462664

ok, semphr = 268465112

semaphore delete... 268464992

ok, semphr = 268469624

semaphore delete... 268469504

ok, semphr = 268469960

semaphore delete... 268469840

Крайний семафор был создан в задаче, отвечающей за обработку принятого EMAC пакета и передачу его дальше.

На этом всё просто зависает. Временное отсутствие рабочего отладчика затрудняет дебаг.

 

Пробовал останавливать все задачи перед удалением семафоров (vTaskSuspendAll()), отключать все прерывания, увеличивать приоритет треда, выходить из треда после удаления каждого семафора (т.е. давать айдлу возможность освободить память) - не помогает, так же всё виснет после удаления 6 семафоров.

Подскажите как попробовать ещё или как иначе лучше решить задачу с перезапуском lwip?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конкретно виснет в vPortFree()::prvInsertBlockIntoFreeList() на

    for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
    {
        /* Nothing to do here, just iterate to the right position. */
    }

С heap_2 и heap_4 одинаково.

Причём такая проблема только с семафорами и очередями созданными в одном треде. Если проигнорировать семафоры и очереди именно из этого треда то всё проходит нормально. Правда всё равно не работает то что задумано и виснет на создании основного треда lwip, но это по идее другая история

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно проверить как будет вести себя мой аллокатор:

http://electronix.ru/forum/index.php?showt...15&start=15

Был сделан из-за такого же рода ошибок.

lwip вроде бы свои собственные (не RTOS) семафоры и очереди использует.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно проверить как будет вести себя мой аллокатор:

http://electronix.ru/forum/index.php?showt...15&start=15

Был сделан из-за такого же рода ошибок.

lwip вроде бы свои собственные (не RTOS) семафоры и очереди использует.

Спасибо! Попробую сегодня

lwip использует семафоры от ртос. Обёртки для работы с ними в sys_arch.{c,h} пишутся. Вроде кроме это больше ничего подобного в нём нет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

lwip использует семафоры от ртос....

 

долго наблюдал этот топик...

в своё время не прокатило останов/удаление потока из вне. если присмотреться к типовым решениям, то обычно это делается из того-же самого потока. т.е. поток получает команд - убейся, идёт и грохает свой хэндл. может тут собака порылась у вас? (насколько я увидел в вашем кусочке кода - Вы грохаете потоки из вне).

 

справка:

проблем с освобождением кучи хэнделов, семафоров, очередей, остановом фриртос не испытываю. всё шутдаунится замечательно. Правда пришлось допиливать в разрезе остановки-портирования(ну и немного переписать азм вставки). данная ось имеет мелкие косячки, но не в плане семафоров...

 

 

это типа как ышо одна мысля...

Изменено пользователем kolobok0

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость MALLOY2

Зачем его перезапускать ? Стек работает годами без каких либо глюков, ищите проблему в другом месте, а не грабли прикрывайте листьями. А если по делу, что бы сильно не вникать в кишки lwip, создайте список всех созданных lwip хендлов, потом зарубать задачу lwip, потом в цикле все хендлы, потом заново создать задачу. Но еще раз это не правильно LWIP проверен годами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

долго наблюдал этот топик...

в своё время не прокатило останов/удаление потока из вне. если присмотреться к типовым решениям, то обычно это делается из того-же самого потока. т.е. поток получает команд - убейся, идёт и грохает свой хэндл. может тут собака порылась у вас? (насколько я увидел в вашем кусочке кода - Вы грохаете потоки из вне)

Да, в некоторых высокоуровневых ЯП только так и можно прибить тред. Но добавляется слишком много гемора из-за блокирующих операций в треде. А реализовать это уже могут быть большие изменения в коде самого lwip.

 

Зачем его перезапускать ? Стек работает годами без каких либо глюков, ищите проблему в другом месте, а не грабли прикрывайте листьями. А если по делу, что бы сильно не вникать в кишки lwip, создайте список всех созданных lwip хендлов, потом зарубать задачу lwip, потом в цикле все хендлы, потом заново создать задачу. Но еще раз это не правильно LWIP проверен годами.

По-хорошему - да. Но разобраться с этой проблемой в данном проекте не удалось ни мне ни ещё нескольким людям. Поэтому было принято решение прикрывать грабли листьями. Было бы здорово если Вы хорошо разбираетесь в lwip и помогли бы справится с этой проблемой за $.

 

wave48, с Вашим выделятором кажется нашёл утечку памяти в проекте. Сначала были такие глюки как в первом посте описаны. Потом другие люди вносили изменения в проект, причём совсем в другую его часть. Потом у меня начал вываливаться malloc hook в ртосе. Не вдаваясь в подробности попробовал Ваш выделатор - тоже самое, в какой-то момент malloc_z() возвращает NULL. Видимо где-то тут собака порылась.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

wave48, с Вашим выделятором кажется нашёл утечку памяти в проекте. Сначала были такие глюки как в первом посте описаны. Потом другие люди вносили изменения в проект, причём совсем в другую его часть. Потом у меня начал вываливаться malloc hook в ртосе. Не вдаваясь в подробности попробовал Ваш выделатор - тоже самое, в какой-то момент malloc_z() возвращает NULL. Видимо где-то тут собака порылась.

 

Рост кучи в нем легко увидеть, посмотрев в отладчике что происходит с system_heap. malloc_z() может не выделить память только если размер кучи этого не позволяет. Можно и нужно делать дефрагментацию кучи, вызывая по таймеру defragHeap(). Скорее всего, кто-то забыл про то что нужно память освобождать. ;-)) Есть специальная функция для определения возможности получения памяти - getHeapMaxSize(). Успехов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...