RT-Thread / rt-thread

RT-Thread is an open source IoT Real-Time Operating System (RTOS).
https://www.rt-thread.io
Apache License 2.0
10.47k stars 5.01k forks source link

workqueue.c 中 rt_workqueue_submit_work bug #8477

Open yuqingli05 opened 9 months ago

yuqingli05 commented 9 months ago

RT-Thread 版本:4.1.x,5.1.0 ,其他版本没验证 应该也存在 问题描述 rt_workqueue_submit_work 延迟任务执行,如果在定时到达之前,提前重新调用并传参tick=0,会导致定时到达之后出现bug。

问题复现代码,bsp:qemu-vexpress-a9 main.c 如下

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <rtthread.h>

struct rt_work test_work;

void work_func(struct rt_work *work, void *work_data)
{
    printf("work_func %lu\n", rt_tick_get_millisecond());
}

int main(void)
{
    rt_thread_mdelay(200);
    printf("Hello RT-Thread!\n");

    rt_work_init(&test_work, work_func, NULL);

    printf("main %lu\n", rt_tick_get_millisecond());
    rt_work_submit(&test_work, rt_tick_from_millisecond(1000));
    rt_thread_mdelay(200);
    rt_work_submit(&test_work, 0);

    return 0;
}

msh输出如下:

 \ | /
- RT -     Thread Operating System
 / | \     5.1.0 build Jan  9 2024 10:46:20
 2006 - 2022 Copyright by RT-Thread team   
[I/SDIO] SD card capacity 65536 KB.
[I/SDIO] switching card to high speed failed!
[I/FileSystem] file system initialization done!

msh />Hello RT-Thread!
main 1220
work_func 1420
(queue != RT_NULL) assertion failed at function:_delayed_work_timeout_handler, line number:176 
backtrace:
please use: addr2line -e rtthread.elf -a -f 6003fe10 6004c848 60057fb4 60053454 6005361c       

问题分析:

_workqueue_submit_work 函数当 ticks传参等于0 的时候,没有停止上次的定时器。导致任务触发后,定时还在继续。当定时器触发之后任务已经执行完成。

解决办法: 修改 _workqueue_submit_work 函数,

    if (ticks == 0)
    {
        rt_list_insert_after(queue->work_list.prev, &(work->list));
        work->flags |= RT_WORK_STATE_PENDING;
        work->workqueue = queue;

        if (work->flags & RT_WORK_STATE_SUBMITTING)
        {
            rt_timer_stop(&(work->timer));
            rt_timer_detach(&(work->timer));
            work->flags &= ~RT_WORK_STATE_SUBMITTING;
        }
.
.
.
BernardXiong commented 9 months ago

欢迎提交修正的PR

yuqingli05 commented 9 months ago

欢迎提交修正的PR

我在某个项目中有大量的使用 workqueue 模块。我发现 struct rt_work 结构体会占用大量的内存,原因在于每个 struct rt_work 都包含一个定时器。我实际使用中已经 部分重构 workqueue 模块模块。不在依赖定时器。如果有必要我可以提交我的代码pr,请回复我是否有必要pr。

Rbb666 commented 9 months ago

欢迎提交修正的PR

我在某个项目中有大量的使用 workqueue 模块。我发现 struct rt_work 结构体会占用大量的内存,原因在于每个 struct rt_work 都包含一个定时器。我实际使用中已经 部分重构 workqueue 模块模块。不在依赖定时器。如果有必要我可以提交我的代码pr,请回复我是否有必要pr。

可以先提上来看看呀