diff options
| author | sheltonyu <[email protected]> | 2021-04-13 11:37:46 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-04-13 11:37:46 +0800 |
| commit | 46c5ba9225702bf473646ec2f4200c9560e2db90 (patch) | |
| tree | a7fe59ac9ce9a6a1c90d9c81324a4a6bb91b38a4 /components/drivers/src | |
| parent | 35ef1f9e0fcf1ae881a83558dbf7334ab08c598e (diff) | |
| parent | c44e5165bef5b7b069eb99a4f027454f417a726b (diff) | |
Merge branch 'master' into developer
Diffstat (limited to 'components/drivers/src')
| -rw-r--r-- | components/drivers/src/completion.c | 2 | ||||
| -rw-r--r-- | components/drivers/src/dataqueue.c | 28 | ||||
| -rw-r--r-- | components/drivers/src/pipe.c | 22 | ||||
| -rw-r--r-- | components/drivers/src/ringblk_buf.c | 44 | ||||
| -rw-r--r-- | components/drivers/src/ringbuffer.c | 12 | ||||
| -rw-r--r-- | components/drivers/src/waitqueue.c | 6 | ||||
| -rw-r--r-- | components/drivers/src/workqueue.c | 291 |
7 files changed, 175 insertions, 230 deletions
diff --git a/components/drivers/src/completion.c b/components/drivers/src/completion.c index 9e461e49ce..b91ae3d6dc 100644 --- a/components/drivers/src/completion.c +++ b/components/drivers/src/completion.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/components/drivers/src/dataqueue.c b/components/drivers/src/dataqueue.c index 1651417bb9..f32efa1849 100644 --- a/components/drivers/src/dataqueue.c +++ b/components/drivers/src/dataqueue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -62,7 +62,7 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue, rt_ubase_t level; rt_thread_t thread; rt_err_t result; - + RT_ASSERT(queue != RT_NULL); RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); @@ -85,7 +85,7 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue, /* reset thread error number */ thread->error = RT_EOK; - + /* suspend thread on the push list */ rt_thread_suspend(thread); rt_list_insert_before(&(queue->suspended_push_list), &(thread->tlist)); @@ -155,13 +155,13 @@ RTM_EXPORT(rt_data_queue_push); rt_err_t rt_data_queue_pop(struct rt_data_queue *queue, const void** data_ptr, - rt_size_t *size, + rt_size_t *size, rt_int32_t timeout) { rt_ubase_t level; rt_thread_t thread; rt_err_t result; - + RT_ASSERT(queue != RT_NULL); RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); RT_ASSERT(data_ptr != RT_NULL); @@ -185,7 +185,7 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue, /* reset thread error number */ thread->error = RT_EOK; - + /* suspend thread on the pop list */ rt_thread_suspend(thread); rt_list_insert_before(&(queue->suspended_pop_list), &(thread->tlist)); @@ -269,11 +269,11 @@ rt_err_t rt_data_queue_peek(struct rt_data_queue *queue, rt_size_t *size) { rt_ubase_t level; - + RT_ASSERT(queue != RT_NULL); RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); - if (queue->is_empty) + if (queue->is_empty) { return -RT_EEMPTY; } @@ -293,7 +293,7 @@ void rt_data_queue_reset(struct rt_data_queue *queue) { rt_ubase_t level; struct rt_thread *thread; - + RT_ASSERT(queue != RT_NULL); RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); @@ -303,9 +303,9 @@ void rt_data_queue_reset(struct rt_data_queue *queue) queue->put_index = 0; queue->is_empty = 1; queue->is_full = 0; - + rt_hw_interrupt_enable(level); - + rt_enter_critical(); /* wakeup all suspend threads */ @@ -375,7 +375,7 @@ rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue) level = rt_hw_interrupt_disable(); queue->magic = 0; rt_hw_interrupt_enable(level); - + rt_free(queue->queue); return RT_EOK; @@ -386,7 +386,7 @@ rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue) { rt_ubase_t level; rt_int16_t len; - + RT_ASSERT(queue != RT_NULL); RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); @@ -405,7 +405,7 @@ rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue) { len = queue->size + queue->put_index - queue->get_index; } - + rt_hw_interrupt_enable(level); return len; diff --git a/components/drivers/src/pipe.c b/components/drivers/src/pipe.c index bd392cba2b..236c1ffec7 100644 --- a/components/drivers/src/pipe.c +++ b/components/drivers/src/pipe.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -320,7 +320,7 @@ static const struct dfs_file_ops pipe_fops = }; #endif /* end of RT_USING_POSIX */ -rt_err_t rt_pipe_open (rt_device_t device, rt_uint16_t oflag) +rt_err_t rt_pipe_open(rt_device_t device, rt_uint16_t oflag) { rt_pipe_t *pipe = (rt_pipe_t *)device; rt_err_t ret = RT_EOK; @@ -330,7 +330,7 @@ rt_err_t rt_pipe_open (rt_device_t device, rt_uint16_t oflag) ret = -RT_EINVAL; goto __exit; } - + rt_mutex_take(&(pipe->lock), RT_WAITING_FOREVER); if (pipe->fifo == RT_NULL) @@ -348,7 +348,7 @@ __exit: return ret; } -rt_err_t rt_pipe_close (rt_device_t device) +rt_err_t rt_pipe_close(rt_device_t device) { rt_pipe_t *pipe = (rt_pipe_t *)device; @@ -366,7 +366,7 @@ rt_err_t rt_pipe_close (rt_device_t device) return RT_EOK; } -rt_size_t rt_pipe_read (rt_device_t device, rt_off_t pos, void *buffer, rt_size_t count) +rt_size_t rt_pipe_read(rt_device_t device, rt_off_t pos, void *buffer, rt_size_t count) { uint8_t *pbuf; rt_size_t read_bytes = 0; @@ -394,7 +394,7 @@ rt_size_t rt_pipe_read (rt_device_t device, rt_off_t pos, void *buffer, rt_siz return read_bytes; } -rt_size_t rt_pipe_write (rt_device_t device, rt_off_t pos, const void *buffer, rt_size_t count) +rt_size_t rt_pipe_write(rt_device_t device, rt_off_t pos, const void *buffer, rt_size_t count) { uint8_t *pbuf; rt_size_t write_bytes = 0; @@ -428,7 +428,7 @@ rt_err_t rt_pipe_control(rt_device_t dev, int cmd, void *args) } #ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops pipe_ops = +const static struct rt_device_ops pipe_ops = { RT_NULL, rt_pipe_open, @@ -507,7 +507,7 @@ int rt_pipe_delete(const char *name) rt_device_unregister(device); /* close fifo ringbuffer */ - if (pipe->fifo) + if (pipe->fifo) { rt_ringbuffer_destroy(pipe->fifo); pipe->fifo = RT_NULL; @@ -531,8 +531,8 @@ int rt_pipe_delete(const char *name) int pipe(int fildes[2]) { rt_pipe_t *pipe; - char dname[8]; - char dev_name[32]; + char dname[RT_NAME_MAX]; + char dev_name[RT_NAME_MAX * 4]; static int pipeno = 0; rt_snprintf(dname, sizeof(dname), "pipe%d", pipeno++); @@ -564,7 +564,7 @@ int pipe(int fildes[2]) int mkfifo(const char *path, mode_t mode) { rt_pipe_t *pipe; - + pipe = rt_pipe_create(path, PIPE_BUFSZ); if (pipe == RT_NULL) { diff --git a/components/drivers/src/ringblk_buf.c b/components/drivers/src/ringblk_buf.c index 7d83149c5e..c6688b3d2b 100644 --- a/components/drivers/src/ringblk_buf.c +++ b/components/drivers/src/ringblk_buf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -50,26 +50,26 @@ RTM_EXPORT(rt_rbb_init); * @param buf_size buffer size * @param blk_max_num max block number * - * @return != NULL: ring block buffer object - * NULL: create failed + * @return != RT_NULL: ring block buffer object + * RT_NULL: create failed */ rt_rbb_t rt_rbb_create(rt_size_t buf_size, rt_size_t blk_max_num) { - rt_rbb_t rbb = NULL; + rt_rbb_t rbb = RT_NULL; rt_uint8_t *buf; rt_rbb_blk_t blk_set; rbb = (rt_rbb_t)rt_malloc(sizeof(struct rt_rbb)); if (!rbb) { - return NULL; + return RT_NULL; } buf = (rt_uint8_t *)rt_malloc(buf_size); if (!buf) { rt_free(rbb); - return NULL; + return RT_NULL; } blk_set = (rt_rbb_blk_t)rt_malloc(sizeof(struct rt_rbb_blk) * blk_max_num); @@ -77,7 +77,7 @@ rt_rbb_t rt_rbb_create(rt_size_t buf_size, rt_size_t blk_max_num) { rt_free(buf); rt_free(rbb); - return NULL; + return RT_NULL; } rt_rbb_init(rbb, buf, buf_size, blk_set, blk_max_num); @@ -116,7 +116,7 @@ static rt_rbb_blk_t find_empty_blk_in_set(rt_rbb_t rbb) } } - return NULL; + return RT_NULL; } /** @@ -127,14 +127,14 @@ static rt_rbb_blk_t find_empty_blk_in_set(rt_rbb_t rbb) * * @note When your application need align access, please make the blk_szie is aligned. * - * @return != NULL: allocated block - * NULL: allocate failed + * @return != RT_NULL: allocated block + * RT_NULL: allocate failed */ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size) { rt_base_t level; rt_size_t empty1 = 0, empty2 = 0; - rt_rbb_blk_t head, tail, new_rbb = NULL; + rt_rbb_blk_t head, tail, new_rbb = RT_NULL; RT_ASSERT(rbb); RT_ASSERT(blk_size < (1L << 24)); @@ -178,7 +178,7 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size) else { /* no space */ - new_rbb = NULL; + new_rbb = RT_NULL; } } else @@ -202,7 +202,7 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size) else { /* no space */ - new_rbb = NULL; + new_rbb = RT_NULL; } } } @@ -217,7 +217,7 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size) } else { - new_rbb = NULL; + new_rbb = RT_NULL; } rt_hw_interrupt_enable(level); @@ -245,13 +245,13 @@ RTM_EXPORT(rt_rbb_blk_put); * * @param rbb ring block buffer object * - * @return != NULL: block - * NULL: get failed + * @return != RT_NULL: block + * RT_NULL: get failed */ rt_rbb_blk_t rt_rbb_blk_get(rt_rbb_t rbb) { rt_base_t level; - rt_rbb_blk_t block = NULL; + rt_rbb_blk_t block = RT_NULL; rt_slist_t *node; RT_ASSERT(rbb); @@ -271,7 +271,7 @@ rt_rbb_blk_t rt_rbb_blk_get(rt_rbb_t rbb) } } /* not found */ - block = NULL; + block = RT_NULL; __exit: @@ -364,7 +364,7 @@ rt_size_t rt_rbb_blk_queue_get(rt_rbb_t rbb, rt_size_t queue_data_len, rt_rbb_bl rt_base_t level; rt_size_t data_total_size = 0; rt_slist_t *node; - rt_rbb_blk_t last_block = NULL, block; + rt_rbb_blk_t last_block = RT_NULL, block; RT_ASSERT(rbb); RT_ASSERT(blk_queue); @@ -388,7 +388,7 @@ rt_size_t rt_rbb_blk_queue_get(rt_rbb_t rbb, rt_size_t queue_data_len, rt_rbb_bl else { /* the first block must be put status */ - last_block = NULL; + last_block = RT_NULL; continue; } } @@ -493,7 +493,7 @@ rt_size_t rt_rbb_next_blk_queue_len(rt_rbb_t rbb) rt_base_t level; rt_size_t data_len = 0; rt_slist_t *node; - rt_rbb_blk_t last_block = NULL, block; + rt_rbb_blk_t last_block = RT_NULL, block; RT_ASSERT(rbb); @@ -510,7 +510,7 @@ rt_size_t rt_rbb_next_blk_queue_len(rt_rbb_t rbb) if (last_block->status != RT_RBB_BLK_PUT) { /* the first block must be put status */ - last_block = NULL; + last_block = RT_NULL; continue; } } diff --git a/components/drivers/src/ringbuffer.c b/components/drivers/src/ringbuffer.c index 88afd19506..29de20b087 100644 --- a/components/drivers/src/ringbuffer.c +++ b/components/drivers/src/ringbuffer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -320,8 +320,8 @@ rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch) } RTM_EXPORT(rt_ringbuffer_getchar); -/** - * get the size of data in rb +/** + * get the size of data in rb */ rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb) { @@ -341,8 +341,8 @@ rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb) } RTM_EXPORT(rt_ringbuffer_data_len); -/** - * empty the rb +/** + * empty the rb */ void rt_ringbuffer_reset(struct rt_ringbuffer *rb) { @@ -362,7 +362,7 @@ struct rt_ringbuffer* rt_ringbuffer_create(rt_uint16_t size) struct rt_ringbuffer *rb; rt_uint8_t *pool; - RT_ASSERT(size > 0); + RT_ASSERT(size > 0); size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE); diff --git a/components/drivers/src/waitqueue.c b/components/drivers/src/waitqueue.c index 02240edbdf..7fe75a51ba 100644 --- a/components/drivers/src/waitqueue.c +++ b/components/drivers/src/waitqueue.c @@ -1,11 +1,11 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes - * 2018/06/26 Bernard Fix the wait queue issue when wakeup a soon + * 2018/06/26 Bernard Fix the wait queue issue when wakeup a soon * to blocked thread. */ @@ -121,7 +121,7 @@ int rt_wqueue_wait(rt_wqueue_t *queue, int condition, int msec) level = rt_hw_interrupt_disable(); __exit_wakeup: - queue->flag = 0; + queue->flag = RT_WQ_FLAG_CLEAN; rt_hw_interrupt_enable(level); rt_wqueue_remove(&__wait); diff --git a/components/drivers/src/workqueue.c b/components/drivers/src/workqueue.c index 2b5630d8d0..f195dad927 100644 --- a/components/drivers/src/workqueue.c +++ b/components/drivers/src/workqueue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -58,15 +58,17 @@ static void _workqueue_thread_entry(void *parameter) while (1) { + level = rt_hw_interrupt_disable(); if (rt_list_isempty(&(queue->work_list))) { /* no software timer exist, suspend self. */ rt_thread_suspend(rt_thread_self()); + rt_hw_interrupt_enable(level); rt_schedule(); + continue; } /* we have work to do with. */ - level = rt_hw_interrupt_disable(); work = rt_list_entry(queue->work_list.next, struct rt_work, list); rt_list_remove(&(work->list)); queue->work_current = work; @@ -76,175 +78,134 @@ static void _workqueue_thread_entry(void *parameter) /* do work */ work->work_func(work, work->work_data); - level = rt_hw_interrupt_disable(); /* clean current work */ queue->work_current = RT_NULL; - rt_hw_interrupt_enable(level); /* ack work completion */ _workqueue_work_completion(queue); } } -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; + rt_err_t err; 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; + err = RT_EOK; + } + else + { + err = -RT_EBUSY; + } + + /* whether the workqueue is doing work */ + if (queue->work_current == RT_NULL && + ((queue->work_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)) + { + /* resume work thread */ + rt_thread_resume(queue->work_thread); + rt_hw_interrupt_enable(level); + rt_schedule(); + } + else + { + rt_hw_interrupt_enable(level); + } + return err; } - 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; + /* insert delay work list */ + rt_list_insert_after(queue->delayed_list.prev, &(work->list)); 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) { rt_base_t level; + rt_err_t err; level = rt_hw_interrupt_disable(); - if (queue->work_current == work) - { - rt_hw_interrupt_enable(level); - return -RT_EBUSY; - } rt_list_remove(&(work->list)); work->flags &= ~RT_WORK_STATE_PENDING; - rt_hw_interrupt_enable(level); - - return RT_EOK; -} - -static rt_err_t _workqueue_cancel_delayed_work(struct rt_work *work) -{ - rt_base_t level; - int ret = RT_EOK; - - if (!work->workqueue) - { - ret = -EINVAL; - goto __exit; - } - - if (work->flags & RT_WORK_STATE_PENDING) - { - /* Remove from the queue if already submitted */ - ret = _workqueue_cancel_work(work->workqueue, work); - if (ret) - { - goto __exit; - } - } - else + /* Timer started */ + if (work->flags & RT_WORK_STATE_SUBMITTING) { - if (work->flags & RT_WORK_STATE_SUBMITTING) - { - level = rt_hw_interrupt_disable(); - rt_timer_stop(&(work->timer)); - rt_timer_detach(&(work->timer)); - work->flags &= ~RT_WORK_STATE_SUBMITTING; - rt_hw_interrupt_enable(level); - } + rt_timer_stop(&(work->timer)); + rt_timer_detach(&(work->timer)); + work->flags &= ~RT_WORK_STATE_SUBMITTING; } - - level = rt_hw_interrupt_disable(); - /* Detach from workqueue */ + err = queue->work_current != work ? RT_EOK : -RT_EBUSY; work->workqueue = RT_NULL; - work->flags &= ~(RT_WORK_STATE_PENDING); rt_hw_interrupt_enable(level); - -__exit: - return ret; + return err; } -static rt_err_t _workqueue_submit_delayed_work(struct rt_workqueue *queue, - struct rt_work *work, rt_tick_t ticks) +static void _delayed_work_timeout_handler(void *parameter) { + struct rt_work *work; + struct rt_workqueue *queue; 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; - } + work = (struct rt_work *)parameter; + queue = work->workqueue; + RT_ASSERT(queue != RT_NULL); - /* Cancel if work has been submitted */ - if (work->workqueue == queue) + level = rt_hw_interrupt_disable(); + rt_timer_detach(&(work->timer)); + work->flags &= ~RT_WORK_STATE_SUBMITTING; + /* remove delay list */ + rt_list_remove(&(work->list)); + /* insert work queue */ + if (queue->work_current != work) { - ret = _workqueue_cancel_delayed_work(work); - if (ret < 0) - { - goto __exit; - } + rt_list_insert_after(queue->work_list.prev, &(work->list)); + work->flags |= RT_WORK_STATE_PENDING; } - - level = rt_hw_interrupt_disable(); - /* Attach workqueue so the timeout callback can submit it */ - work->workqueue = queue; - rt_hw_interrupt_enable(level); - - if (!ticks) + /* whether the workqueue is doing work */ + if (queue->work_current == RT_NULL && + ((queue->work_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)) { - /* Submit work if no ticks is 0 */ - ret = _workqueue_submit_work(work->workqueue, work); + /* resume work thread */ + rt_thread_resume(queue->work_thread); + rt_hw_interrupt_enable(level); + rt_schedule(); } 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; - rt_base_t level; - - delayed_work = (struct rt_work *)parameter; - level = rt_hw_interrupt_disable(); - rt_timer_stop(&(delayed_work->timer)); - rt_timer_detach(&(delayed_work->timer)); - 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); } struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority) @@ -256,6 +217,7 @@ struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_siz { /* initialize work list */ rt_list_init(&(queue->work_list)); + rt_list_init(&(queue->delayed_list)); queue->work_current = RT_NULL; rt_sem_init(&(queue->sem), "wqueue", 0, RT_IPC_FLAG_FIFO); @@ -277,7 +239,9 @@ rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue) { RT_ASSERT(queue != RT_NULL); + rt_workqueue_cancel_all_work(queue); rt_thread_delete(queue->work_thread); + rt_sem_detach(&(queue->sem)); RT_KERNEL_FREE(queue); return RT_EOK; @@ -288,7 +252,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) @@ -296,19 +260,7 @@ rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *wo RT_ASSERT(queue != RT_NULL); RT_ASSERT(work != RT_NULL); - if (time > 0) - { - work->type |= RT_WORK_TYPE_DELAYED; - } - - if (work->type & RT_WORK_TYPE_DELAYED) - { - return _workqueue_submit_delayed_work(queue, work, time); - } - else - { - return _workqueue_submit_work(queue, work); - } + return _workqueue_submit_work(queue, work, time); } rt_err_t rt_workqueue_critical_work(struct rt_workqueue *queue, struct rt_work *work) @@ -318,51 +270,38 @@ rt_err_t rt_workqueue_critical_work(struct rt_workqueue *queue, struct rt_work * RT_ASSERT(work != RT_NULL); level = rt_hw_interrupt_disable(); - if (queue->work_current == work) - { - rt_hw_interrupt_enable(level); - return -RT_EBUSY; - } - /* NOTE: the work MUST be initialized firstly */ rt_list_remove(&(work->list)); - - rt_list_insert_after(queue->work_list.prev, &(work->list)); - if (queue->work_current == RT_NULL) + rt_list_insert_after(&queue->work_list, &(work->list)); + /* 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_hw_interrupt_enable(level); rt_schedule(); } - else rt_hw_interrupt_enable(level); + else + { + rt_hw_interrupt_enable(level); + } return RT_EOK; } rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work) { - RT_ASSERT(queue != RT_NULL); RT_ASSERT(work != RT_NULL); - - if (work->type & RT_WORK_TYPE_DELAYED) - { - return _workqueue_cancel_delayed_work(work); - } - else - { - return _workqueue_cancel_work(queue, work); - } + RT_ASSERT(queue != RT_NULL); + return _workqueue_cancel_work(queue, work); } rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_work *work) { - rt_base_t level; - RT_ASSERT(queue != RT_NULL); RT_ASSERT(work != RT_NULL); - level = rt_hw_interrupt_disable(); if (queue->work_current == work) /* it's current work in the queue */ { /* wait for work completion */ @@ -370,24 +309,30 @@ rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_wor } else { - rt_list_remove(&(work->list)); + _workqueue_cancel_work(queue, work); } - work->flags &= ~RT_WORK_STATE_PENDING; - rt_hw_interrupt_enable(level); return RT_EOK; } rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue) { - struct rt_list_node *node, *next; + struct rt_work *work; + RT_ASSERT(queue != RT_NULL); + /* cancel work */ rt_enter_critical(); - for (node = queue->work_list.next; node != &(queue->work_list); node = next) + while (rt_list_isempty(&queue->work_list) == RT_FALSE) + { + work = rt_list_first_entry(&queue->work_list, struct rt_work, list); + _workqueue_cancel_work(queue, work); + } + /* cancel delay work */ + while (rt_list_isempty(&queue->delayed_list) == RT_FALSE) { - next = node->next; - rt_list_remove(node); + work = rt_list_first_entry(&queue->delayed_list, struct rt_work, list); + _workqueue_cancel_work(queue, work); } rt_exit_critical(); @@ -416,14 +361,14 @@ rt_err_t rt_work_cancel(struct rt_work *work) int rt_work_sys_workqueue_init(void) { if (sys_workq != RT_NULL) - return 0; + return RT_EOK; sys_workq = rt_workqueue_create("sys_work", RT_SYSTEM_WORKQUEUE_STACKSIZE, RT_SYSTEM_WORKQUEUE_PRIORITY); + RT_ASSERT(sys_workq != RT_NULL); return RT_EOK; } - INIT_PREV_EXPORT(rt_work_sys_workqueue_init); #endif #endif |
