From 0c87becb3eed0e890198740589f0db94ab6256cf Mon Sep 17 00:00:00 2001 From: tangyuxin Date: Sat, 30 Jan 2021 18:21:33 +0800 Subject: 合并 submit 和 submit_delayed,优化代码体积 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 _workqueue_submit_delayed_work 和 _workqueue_submit_work 函数合并成一个。优化代码体积 --- components/drivers/src/workqueue.c | 128 ++++++++++++++----------------------- 1 file changed, 49 insertions(+), 79 deletions(-) diff --git a/components/drivers/src/workqueue.c b/components/drivers/src/workqueue.c index 2b5630d8d0..557f349e53 100644 --- a/components/drivers/src/workqueue.c +++ b/components/drivers/src/workqueue.c @@ -86,43 +86,61 @@ static void _workqueue_thread_entry(void *parameter) } } -static rt_err_t _workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work) +static rt_err_t _workqueue_submit_work(struct rt_workqueue *queue, + struct rt_work *work, rt_tick_t ticks) { rt_base_t level; level = rt_hw_interrupt_disable(); - if (work->flags & RT_WORK_STATE_PENDING) - { - rt_hw_interrupt_enable(level); - return -RT_EBUSY; - } - - if (queue->work_current == work) - { - rt_hw_interrupt_enable(level); - return -RT_EBUSY; - } - - /* NOTE: the work MUST be initialized firstly */ + /* remove list */ rt_list_remove(&(work->list)); - - rt_list_insert_after(queue->work_list.prev, &(work->list)); - work->flags |= RT_WORK_STATE_PENDING; - - /* whether the workqueue is doing work */ - if (queue->work_current == RT_NULL) + work->flags &= ~RT_WORK_STATE_PENDING; + /* */ + if (ticks == 0) { - rt_hw_interrupt_enable(level); - /* resume work thread */ - rt_thread_resume(queue->work_thread); - rt_schedule(); + if (queue->work_current != work) + { + rt_list_insert_after(queue->work_list.prev, &(work->list)); + work->flags |= RT_WORK_STATE_PENDING; + work->workqueue = queue; + } + + /* whether the workqueue is doing work */ + if (queue->work_current == RT_NULL && + ((queue->work_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)) + { + rt_hw_interrupt_enable(level); + /* resume work thread */ + rt_thread_resume(queue->work_thread); + rt_schedule(); + } + else + { + rt_hw_interrupt_enable(level); + } + return RT_EOK; } - else + else if (ticks < RT_TICK_MAX / 2) { + /* Timer started */ + if (work->flags & RT_WORK_STATE_SUBMITTING) + { + rt_timer_stop(&work->timer); + rt_timer_control(&work->timer, RT_TIMER_CTRL_SET_TIME, &ticks); + } + else + { + rt_timer_init(&(work->timer), "work", _delayed_work_timeout_handler, + work, ticks, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); + work->flags |= RT_WORK_STATE_SUBMITTING; + } + work->workqueue = queue; rt_hw_interrupt_enable(level); + rt_timer_start(&(work->timer)); + return RT_EOK; } - - return RT_EOK; + rt_hw_interrupt_enable(level); + return -RT_ERROR; } static rt_err_t _workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work) @@ -184,54 +202,6 @@ __exit: return ret; } -static rt_err_t _workqueue_submit_delayed_work(struct rt_workqueue *queue, - struct rt_work *work, rt_tick_t ticks) -{ - rt_base_t level; - rt_err_t ret = RT_EOK; - - /* Work cannot be active in multiple queues */ - if (work->workqueue && work->workqueue != queue) - { - ret = -RT_EINVAL; - goto __exit; - } - - /* Cancel if work has been submitted */ - if (work->workqueue == queue) - { - ret = _workqueue_cancel_delayed_work(work); - if (ret < 0) - { - goto __exit; - } - } - - level = rt_hw_interrupt_disable(); - /* Attach workqueue so the timeout callback can submit it */ - work->workqueue = queue; - rt_hw_interrupt_enable(level); - - if (!ticks) - { - /* Submit work if no ticks is 0 */ - ret = _workqueue_submit_work(work->workqueue, work); - } - else - { - level = rt_hw_interrupt_disable(); - /* Add timeout */ - work->flags |= RT_WORK_STATE_SUBMITTING; - rt_timer_init(&(work->timer), "work", _delayed_work_timeout_handler, work, ticks, - RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); - rt_hw_interrupt_enable(level); - rt_timer_start(&(work->timer)); - } - -__exit: - return ret; -} - static void _delayed_work_timeout_handler(void *parameter) { struct rt_work *delayed_work; @@ -244,7 +214,7 @@ static void _delayed_work_timeout_handler(void *parameter) delayed_work->flags &= ~RT_WORK_STATE_SUBMITTING; delayed_work->type &= ~RT_WORK_TYPE_DELAYED; rt_hw_interrupt_enable(level); - _workqueue_submit_work(delayed_work->workqueue, delayed_work); + _workqueue_submit_work(delayed_work->workqueue, delayed_work, 0); } struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority) @@ -288,7 +258,7 @@ rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work) RT_ASSERT(queue != RT_NULL); RT_ASSERT(work != RT_NULL); - return _workqueue_submit_work(queue, work); + return _workqueue_submit_work(queue, work, 0); } rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t time) @@ -303,11 +273,11 @@ rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *wo if (work->type & RT_WORK_TYPE_DELAYED) { - return _workqueue_submit_delayed_work(queue, work, time); + return _workqueue_submit_work(queue, work, time); } else { - return _workqueue_submit_work(queue, work); + return _workqueue_submit_work(queue, work, 0); } } -- cgit v1.3.1