workqueue 去掉timer,使用list排序处理方式#9825
Conversation
|
|
||
| if (ticks == 0) | ||
| { | ||
| rt_list_insert_after(queue->work_list.prev, &(work->list)); |
There was a problem hiding this comment.
我觉得这里缺少种情况的判断:比如创建一个工作队列,队列执行后再向其提交一次,正常来说第二次应该返回BUSY了
这块我看之前是有判断的,建议作者添加上:b065486#diff-b63048f1ad2089c43aeb589d9f396dfea3e95b253a0e9c7d13f785bc0613cb31L105
There was a problem hiding this comment.
b065486#diff-b63048f1ad2089c43aeb589d9f396dfea3e95b253a0e9c7d13f785bc0613cb31L93-R354
1、看了下上面 b065486 ,这次提交不是去掉BUSY判断用的吗?和我的思路不冲突啊。
2、并且我认为去掉 busy是个明智之举。因为他可以在 自己的回调里面 再次触发自己,这个是很常用的(至少我很常用,我自己的项目里面大量的使用了回调函数里面再次触发同一个 work的逻辑)。
3、正在触发回调的work, b065486 和我的思路是一样的,都是运行再次添加。
4、实际上我为了处理这个问题,在线程回调的地方,把回调函数在临界区保存为临时变量了(work_func 和 work_data)。退出临界区之后实际上 work 结构体已经是安全的了。f0415bb?diff=split&w=0#diff-b63048f1ad2089c43aeb589d9f396dfea3e95b253a0e9c7d13f785bc0613cb31R96-R109
There was a problem hiding this comment.
我没描述清楚,假设这样的条件:工作队列线程回调还没执行完成再次发生了调度,然后在其他线程又向队列提交了一个任务,那么这个时候队列应该处于BUSY吧。
static void work_test_fun(struct rt_work *work, void *work_data)
{
......
rt_thread_delay(10);
......
}
static void repeat_work_test02(void)
{
/* 比当前测试线程优先级高 1 */
curr_priority = get_test_thread_priority(-1);
queue = rt_workqueue_create("test", 2048, curr_priority);
rt_work_init(&work, work_test_fun, (void *)&work_flag);
/* 提交任务,队列优先级高,会立即执行 */
rt_workqueue_submit_work(queue, &work, 0);
/* 延时让出 CPU */
rt_thread_delay(5);
/* 再次提交正在执行的任务,应该返回 BUSY */
err = rt_workqueue_submit_work(queue, &work, 0);
......
}There was a problem hiding this comment.
1、现在需要明确的是:在我这个PR之前,BUSY判断就已经去掉了。我只是沿用他的去掉,我为啥要给他加回去那?
2、你第一条回复的那个提交 b065486 就是去掉 BUSY判断的啊。理由是work正在执行,这时候发生中断,这个中断调用rt_workqueue_submit_work,导致work丢掉。你为啥要用一和你观点完全想法的提交 b065486 来证明你的观点那?我又确认了一遍 b065486 ,好像不是我理解错了把?
3、同时说一下 我认为 去掉BUSY合理的原因如下(个人观点):
static void work_test_fun(struct rt_work *work, void *work_data)
{
// 回调里面直接再次 触发自己,如果存在BUSY状态这个会触发失败
// 至于为什么不用 循环直接执行,我理解是 是要利用 work的先进先出,进行排队执行(都是0延迟的时候),给其他任务执行的 空间
// 我个人在项目中使用这种方式驱动了一个主逻辑
rt_workqueue_submit_work(queue, &work, 0);
}
static void repeat_work_test02(void)
{
rt_work_init(&work, work_test_fun, NULL);
rt_workqueue_submit_work(queue, &work, 0);
}| work->workqueue = queue; | ||
| work->flags |= RT_WORK_STATE_PENDING; | ||
| work->workqueue = queue; | ||
|
|
There was a problem hiding this comment.
我意思是不是在这里加个busy的返回判断就行了,因为我看到rt_workqueue_submit_work API返回值就是存在RT_EBUSY状态的:#L317
err = queue->work_current != work ? RT_EOK : -RT_EBUSY;|
我提交了一份有关工作队列的PR ,@yuqingli05 大佬可以看看:#9850 |
|
我重新出发一下CI |
拉取/合并请求描述:(PR description)
[
并确认并列出已经在什么情况或板卡上进行了测试。
And confirm in which case or board has been tested. -->
bsp\qemu-vexpress-a9
为什么提交这份PR (why to submit this PR)
1、Fixed #9814
2、去掉每个work的定时器,能大量减少 work的内存占用,和性能优化
你的解决方案是什么 (what is your solution)
去掉work的 timer,只需要在 work线程里面 延迟和同步即可
请提供验证的bsp和config (provide the config and bsp)
测试main函数如下
]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up