Skip to content

Commit 2782619

Browse files
committed
[components][ipc][workqueue] 完善 workqueue 同步语义、生命周期收敛与 delayed 队列处理
1 parent 6a635e3 commit 2782619

File tree

7 files changed

+4485
-869
lines changed

7 files changed

+4485
-869
lines changed

components/drivers/include/ipc/workqueue.h

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/*
2-
* Copyright (c) 2006-2023, RT-Thread Development Team
2+
* Copyright (c) 2006-2026, RT-Thread Development Team
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
66
* Change Logs:
77
* Date Author Notes
88
* 2021-08-01 Meco Man remove rt_delayed_work_init() and rt_delayed_work structure
99
* 2021-08-14 Jackistang add comments for rt_work_init()
10+
* 2026-03-21 RyanCW refine sync/status workqueue APIs
1011
*/
1112
#ifndef WORKQUEUE_H__
1213
#define WORKQUEUE_H__
@@ -19,55 +20,87 @@
1920
extern "C" {
2021
#endif
2122

23+
/* Stored in work->flags. Internal runtime state. */
2224
enum
2325
{
24-
RT_WORK_STATE_PENDING = 0x0001, /* Work item pending state */
25-
RT_WORK_STATE_SUBMITTING = 0x0002, /* Work item submitting state */
26+
RT_WORK_STATE_PENDING = 0x0001, /* Work is ready on work_list */
27+
RT_WORK_STATE_SUBMITTING = 0x0002, /* Historical name: work is queued on delayed_list */
28+
RT_WORK_STATE_CANCELING = 0x0004, /* Sync cancel/destroy waiter is targeting this work */
29+
RT_WORK_STATE_DONE = 0x0020, /* Work finished and is no longer queued */
30+
RT_WORK_STATE_CANCELED = 0x0040, /* Work was dropped before execution */
2631
};
2732

2833
/**
29-
* work type definitions
34+
* Work status bits returned by rt_workqueue_get_work_status().
35+
*
36+
* This is a query-only view and is independent from the internal
37+
* RT_WORK_STATE_* storage. Prefer RT_WORK_STATUS_DELAYED in new code;
38+
* RT_WORK_STATUS_SUBMITTING is kept as a compatibility alias.
3039
*/
3140
enum
3241
{
33-
RT_WORK_TYPE_DELAYED = 0x0001,
42+
RT_WORK_STATUS_IDLE = 0x0000, /* Work is idle with no retained terminal state */
43+
RT_WORK_STATUS_PENDING = 0x0001, /* Work is ready on work_list */
44+
RT_WORK_STATUS_DELAYED = 0x0002, /* Work is waiting on delayed_list */
45+
RT_WORK_STATUS_CANCELING = 0x0004, /* A sync cancel/destroy waiter targets this work */
46+
RT_WORK_STATUS_RUNNING = 0x0008, /* Work callback is currently executing */
47+
RT_WORK_STATUS_OTHER_QUEUE = 0x0010, /* Work is bound to a different workqueue */
48+
RT_WORK_STATUS_DONE = 0x0020, /* Work finished and is no longer queued */
49+
RT_WORK_STATUS_CANCELED = 0x0040, /* Work was dropped before execution */
50+
RT_WORK_STATUS_SUBMITTING = RT_WORK_STATUS_DELAYED, /* Compatibility alias of RT_WORK_STATUS_DELAYED */
3451
};
3552

36-
/* workqueue implementation */
37-
struct rt_workqueue
53+
/* Stored in queue->flags. Internal queue control state. */
54+
enum
3855
{
39-
rt_list_t work_list;
40-
rt_list_t delayed_list;
41-
struct rt_work *work_current; /* current work */
56+
RT_WORKQUEUE_FLAG_DESTROYING = 0x01, /* Queue rejects new work and drains to exit */
57+
RT_WORKQUEUE_FLAG_SYNC_WAITING = 0x02, /* One sync waiter is blocked on this queue */
58+
};
4259

43-
struct rt_semaphore sem;
44-
rt_thread_t work_thread;
45-
struct rt_spinlock spinlock;
46-
struct rt_completion wakeup_completion;
60+
/**
61+
* Workqueue runtime object.
62+
*
63+
* The fields below are internal runtime data used by the worker thread,
64+
* submit path and sync-wait paths.
65+
*/
66+
struct rt_workqueue
67+
{
68+
rt_list_t work_list; /* Immediate works ready to run */
69+
rt_list_t delayed_list; /* Delayed works sorted by timeout_tick */
70+
struct rt_work *work_current; /* Work currently executing on work_thread */
71+
rt_thread_t work_thread; /* Worker thread owned by this queue */
72+
struct rt_spinlock spinlock; /* Protects lists, work_current and flags */
73+
struct rt_completion wakeup_completion; /* Wakes worker for new work or delayed-head changes */
74+
struct rt_completion sync_completion; /* Wakes cancel_work_sync/destroy_sync waiter */
75+
rt_uint8_t flags; /* Internal RT_WORKQUEUE_FLAG_* bits */
4776
};
4877

78+
/**
79+
* Work item runtime object.
80+
*
81+
* A work item can be idle, delayed, pending or running. The same object is
82+
* reused across submissions, so terminal state bits may remain until the next
83+
* successful submit.
84+
*/
4985
struct rt_work
5086
{
51-
rt_list_t list;
52-
53-
void (*work_func)(struct rt_work *work, void *work_data);
54-
void *work_data;
55-
rt_uint16_t flags;
56-
rt_uint16_t type;
57-
rt_tick_t timeout_tick;
58-
struct rt_workqueue *workqueue;
87+
rt_list_t list; /* List node used by work_list or delayed_list */
88+
void (*work_func)(struct rt_work *work, void *work_data); /* Work callback */
89+
void *work_data; /* Callback private argument */
90+
rt_uint16_t flags; /* Internal RT_WORK_STATE_* bits */
91+
rt_tick_t timeout_tick; /* Absolute wake tick while queued on delayed_list */
92+
struct rt_workqueue *workqueue; /* Bound queue while queued or running */
5993
};
6094

6195
#ifdef RT_USING_HEAP
62-
/**
63-
* WorkQueue for DeviceDriver
64-
*/
6596
void rt_work_init(struct rt_work *work, void (*work_func)(struct rt_work *work, void *work_data), void *work_data);
6697
struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority);
6798
rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue);
99+
rt_err_t rt_workqueue_destroy_sync(struct rt_workqueue *queue);
68100
rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work);
69101
rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t ticks);
70102
rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work);
103+
rt_uint16_t rt_workqueue_get_work_status(struct rt_workqueue *queue, struct rt_work *work);
71104
rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_work *work);
72105
rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue);
73106
rt_err_t rt_workqueue_urgent_work(struct rt_workqueue *queue, struct rt_work *work);
@@ -76,6 +109,8 @@ rt_err_t rt_workqueue_urgent_work(struct rt_workqueue *queue, struct rt_work *wo
76109
rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t ticks);
77110
rt_err_t rt_work_urgent(struct rt_work *work);
78111
rt_err_t rt_work_cancel(struct rt_work *work);
112+
rt_err_t rt_work_cancel_sync(struct rt_work *work);
113+
rt_uint16_t rt_work_get_status(struct rt_work *work);
79114
#endif /* RT_USING_SYSTEM_WORKQUEUE */
80115

81116
#ifdef __cplusplus

components/drivers/ipc/utest/SConscript

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ if GetDepend(['RT_UTEST_COMPLETION']):
99
src += ['completion_tc.c', 'completion_timeout_tc.c']
1010

1111
if GetDepend(['RT_UTEST_WORKQUEUE']):
12-
src += ['workqueue_tc.c']
12+
src += ['workqueue_tc_basic.c', 'workqueue_tc_cancel.c', 'workqueue_tc_destroy.c']
1313

1414
group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES'], CPPPATH = CPPPATH)
1515

0 commit comments

Comments
 (0)