Jump to content

    
Sign in to follow this  
Cosmojam

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

Recommended Posts

Есть задача сделать программный перезапуск 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?

Share this post


Link to post
Share on other sites

Конкретно виснет в 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, но это по идее другая история

Share this post


Link to post
Share on other sites

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

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

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

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

 

Share this post


Link to post
Share on other sites
Можно проверить как будет вести себя мой аллокатор:

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

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

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

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

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

Share this post


Link to post
Share on other sites
lwip использует семафоры от ртос....

 

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

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

 

справка:

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

 

 

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

Edited by kolobok0

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
долго наблюдал этот топик...

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

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

 

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

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

 

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

Share this post


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

 

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

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this