XFusion API v1.3.0
载入中...
搜索中...
未找到
xf_ctask.c
浏览该文件的文档.
1
11/* ==================== [Includes] ========================================== */
12
13#include "xf_ctask.h"
14#include "../utils/xf_task_queue.h"
15#include "../port/xf_task_port_internal.h"
16#include "../kernel/xf_task_base.h"
17
18#if XF_TASK_CONTEXT_IS_ENABLE
19
20/* ==================== [Defines] =========================================== */
21
22#define TAG "ctask"
23
24/* ==================== [Typedefs] ========================================== */
25
33
40
41/* ==================== [Static Prototypes] ================================= */
42
43static void xf_task_context_entry(void *args);
44static void xf_ctask_reset(xf_task_t task);
45static void xf_ctask_yield(xf_task_manager_t manager);
46static void xf_ctask_resume(xf_task_manager_t manager);
48static void xf_ctask_exec(xf_task_manager_t manager);
49static xf_task_t xf_ctask_constructor(xf_task_manager_t manager, xf_task_func_t func, void *func_arg, uint16_t priority,
50 void *config);
51
52/* ==================== [Static Variables] ================================== */
53
56 .reset = xf_ctask_reset,
57 .exec = xf_ctask_exec,
58 .update = xf_ctask_update
59};
60
61/* ==================== [Macros] ============================================ */
62
67
68/* ==================== [Global Functions] ================================== */
69
70void xf_ctask_delay_with_manager(xf_task_manager_t manager, uint32_t delay_ms)
71{
72 XF_ASSERT(manager, XF_RETURN_VOID, TAG, "manager must not be NULL");
73
75
76 if (task->base.type != XF_TASK_TYPE_CTASK) {
77 XF_LOGE(TAG, "only ctask can use this function");
78 return;
79 }
80
81 int32_t ticks = xf_task_msec_to_ticks(delay_ms);
82
83 task->base.delay = ticks;
84 task->base.wake_up = xf_task_get_ticks() + ticks;
85 xf_ctask_yield(manager);
86
87}
88
89xf_ctask_queue_t xf_ctask_queue_create_with_manager(xf_task_manager_t manager, const size_t size, const size_t count)
90{
91 XF_ASSERT(manager, NULL, TAG, "manager must not be NULL");
92 XF_ASSERT(size, NULL, TAG, "size must not be 0");
93 XF_ASSERT(count, NULL, TAG, "count must not be 0");
94
96 size * count);
97
98 if (ctask_queue == NULL) {
99 XF_LOGE(TAG, "memory alloc failed!");
100 return NULL;
101 }
102
103 xf_bzero(ctask_queue, sizeof(xf_ctask_queue_handle_t) + size * count);
104
105 void *data = (uint8_t *)ctask_queue + sizeof(xf_ctask_queue_handle_t);
106
107 ctask_queue->manager = manager;
108
109 xf_task_queue_init(&ctask_queue->queue, data, size, count);
110 xf_list_init(&ctask_queue->receive_waiting);
111 xf_list_init(&ctask_queue->send_waiting);
112
113 return (xf_ctask_queue_t)ctask_queue;
114}
115
117{
118 XF_ASSERT(queue, XF_RETURN_VOID, TAG, "queue must not be NULL");
119
120 xf_free(queue);
121}
122
123xf_err_t xf_ctask_queue_send(xf_ctask_queue_t queue, void *buffer, uint32_t timeout)
124{
125 XF_ASSERT(queue, XF_ERR_INVALID_ARG, TAG, "queue must not be NULL");
126 XF_ASSERT(buffer, XF_ERR_INVALID_ARG, TAG, "buffer must not be NULL");
127
128 xf_task_queue_t *_queue = &((xf_ctask_queue_handle_t *)queue)->queue;
129 xf_list_t *send_waiting = &((xf_ctask_queue_handle_t *)queue)->send_waiting;
130 xf_list_t *receive_waiting = &((xf_ctask_queue_handle_t *)queue)->receive_waiting;
131 xf_task_manager_t manager = ((xf_ctask_queue_handle_t *)queue)->manager;
133 xf_list_t *queue_node = &((xf_ctask_handle_t *)task)->queue_node;
134 xf_ctask_handle_t *receive_task, *_receive_task;
135
136 // 只有ctask才能调用
137 if (XF_TASK_STATE_RUNNING != task->state) {
138 XF_LOGE(TAG, "task state must RUNNING");
139 return XF_ERR_BUSY;
140 }
141
142 if (XF_TASK_TYPE_CTASK != task->state) {
143 XF_LOGE(TAG, "task must ctask");
145 }
146
147 while (1) {
148 if (xf_task_queue_is_full(_queue)) {
149 xf_list_add_tail(queue_node, send_waiting);
150 // 这里有可能会被接收方唤醒,从而延时未达到timeout
151 xf_ctask_delay_with_manager(manager, timeout);
152 // 达到超时返回发送失败
153 if (task->timeout >= 0) {
154 XF_LOGD(TAG, "queue timeout");
155 return XF_ERR_TIMEOUT;
156 }
157 // 没达到超时进入循环继续进行接下来的超时
158 timeout = -task->timeout;
159 } else {
161
162 // 将 receive_waiting 全部加入就绪,等待调度器选择最合适的任务
163 xf_list_for_each_entry_safe(receive_task, _receive_task, receive_waiting, xf_ctask_handle_t, queue_node) {
164 xf_list_del_init(&receive_task->queue_node);
165 xf_task_trigger(receive_task);
166 }
167
168 return XF_OK;
169 }
170 }
171}
172
174{
175 XF_ASSERT(queue, XF_ERR_INVALID_ARG, TAG, "queue must not be NULL");
176 XF_ASSERT(buffer, XF_ERR_INVALID_ARG, TAG, "buffer must not be NULL");
177
178 xf_task_queue_t *_queue = &((xf_ctask_queue_handle_t *)queue)->queue;
179 xf_list_t *send_waiting = &((xf_ctask_queue_handle_t *)queue)->send_waiting;
180 xf_list_t *receive_waiting = &((xf_ctask_queue_handle_t *)queue)->receive_waiting;
181 xf_task_manager_t manager = ((xf_ctask_queue_handle_t *)queue)->manager;
183 xf_list_t *queue_node = &((xf_ctask_handle_t *)task)->queue_node;
184 xf_ctask_handle_t *send_task, *_send_task;
185
186 // 只有ctask才能调用
187 if (XF_TASK_STATE_RUNNING != task->state) {
188 XF_LOGE(TAG, "task state must RUNNING");
189 return XF_ERR_BUSY;
190 }
191
192 if (XF_TASK_TYPE_CTASK != task->type) {
193 XF_LOGE(TAG, "task must ctask");
195 }
196
197 while (1) {
198 if (xf_task_queue_is_empty(_queue)) {
199 xf_list_add_tail(queue_node, receive_waiting);
200 // 这里有可能会被发送方唤醒,从而延时未达到timeout
201 xf_ctask_delay_with_manager(manager, timeout);
202 // 达到超时返回发送失败
203 if (task->timeout >= 0) {
204 XF_LOGD(TAG, "queue timeout");
205 return XF_ERR_TIMEOUT;
206 }
207 // 没达到超时进入循环继续进行接下来的超时
208 timeout = -task->timeout;
209 } else {
210 xf_task_queue_receive(_queue, buffer);
211
212 // 将send_waiting全部加入就绪,等待调度器选择最合适的任务
213 xf_list_for_each_entry_safe(send_task, _send_task, send_waiting, xf_ctask_handle_t, queue_node) {
214 xf_list_del_init(&send_task->queue_node);
215 xf_task_trigger(send_task);
216 }
217
218 return XF_OK;
219 }
220 }
221}
222
223/* ==================== [Static Functions] ================================== */
224
225static xf_task_t xf_ctask_constructor(xf_task_manager_t manager, xf_task_func_t func, void *func_arg, uint16_t priority,
226 void *config)
227{
228 size_t stack_size = ((xf_ctask_config_t *)config)->stack_size;
229
230 XF_ASSERT(stack_size > 0, NULL, TAG, "args must more than 0");
231
233
234 if (task == NULL) {
235 XF_LOGE(TAG, "memory alloc failed!");
236 return NULL;
237 }
238
239 task->stack = (void *)((uint8_t *)task + sizeof(xf_ctask_handle_t));
240
241 xf_task_base_init(&task->base, manager, XF_TASK_TYPE_CTASK, priority, func, func_arg);
242
243 task->stack_size = ((xf_ctask_config_t *)config)->stack_size;
244 xf_task_context_create(manager, xf_task_context_entry, &task->context, task->stack, task->stack_size);
245
246 xf_list_init(&task->queue_node);
247
248 return (xf_task_t)task;
249}
250
252{
254
255 xf_task_time_t time_ticks = xf_task_get_ticks();
256
257 int32_t timeout = time_ticks - handle->base.wake_up;
258
259 // 转换超时时间,如果大于零则触发超时
260 handle->base.timeout = xf_task_ticks_to_msec(timeout);
261
262 if (timeout >= 0) {
264 }
265
266 // 对超时信号响应
270 }
271
272 // 对事件信号响应
276 }
277
278 return time_ticks;
279}
280
282{
284
285 handle->base.delay = 0;
286
287 xf_task_base_reset(&handle->base);
288
290
292 handle->stack_size);
293
294}
295
296static void xf_task_context_entry(void *args)
297{
298 xf_task_manager_t manager = (xf_task_manager_t)args;
300
301 // 执行任务函数
302 (task->base.func)(task);
303
304 // 函数运行到结尾,设置结尾标志位
306 // 函数运行完毕,回到调度器
307 xf_task_context_swap(manager, &task->context, xf_task_manager_get_context(manager));
308}
309
311{
313
314 // 在函数内才能退出函数
315 if (XF_TASK_STATE_RUNNING != task->base.state) {
316 XF_LOGD(TAG, "task must running");
317 return ;
318 }
319
320 // 跳出函数,进入调度器
321 xf_task_context_swap(manager, &task->context, xf_task_manager_get_context(manager));
322}
323
325{
327
328 // 只有在调度器内才能调用恢复
329 if (XF_TASK_STATE_RUNNING == task->base.state || XF_TASK_STATE_DELETE == task->base.state) {
330 XF_LOGD(TAG, "task must not running and delete");
331 return;
332 }
333
334 // 跳出调度器,进入函数
336 xf_task_context_swap(manager, xf_task_manager_get_context(manager), &task->context);
337}
338
340{
341 xf_ctask_resume(manager);
342}
343
344#endif // XF_TASK_CONTEXT_IS_ENABLE
void xf_ctask_delay_with_manager(xf_task_manager_t manager, uint32_t delay_ms)
ctask 专用 delay 函数,在 ctask 中才能使用。不会影响调度器。
Definition xf_ctask.c:70
xf_err_t xf_ctask_queue_receive(xf_ctask_queue_t queue, void *buffer, uint32_t timeout)
消息队列接收。
Definition xf_ctask.c:173
xf_err_t xf_ctask_queue_send(xf_ctask_queue_t queue, void *buffer, uint32_t timeout)
消息队列发送。
Definition xf_ctask.c:123
#define XF_TASK_TYPE_CTASK
ctask 类型值。 XF_TASK_TYPE_ctask 通过 xf_task_reg.inc 拼接而来。
Definition xf_ctask.h:40
xf_ctask_queue_t xf_ctask_queue_create_with_manager(xf_task_manager_t manager, const size_t size, const size_t count)
创建 ctask 的消息队列。此消息队列仅供 ctask 使用。
Definition xf_ctask.c:89
void * xf_ctask_queue_t
ctask 任务队列句柄。
Definition xf_ctask.h:47
bool xf_task_queue_is_full(const xf_task_queue_t *const queue)
判断队列是否已满。
xf_err_t xf_task_queue_receive(xf_task_queue_t *const queue, void *const buffer)
从队列接收一个元素。
bool xf_task_queue_is_empty(const xf_task_queue_t *const queue)
判断队列是否为空。
xf_err_t xf_task_queue_init(xf_task_queue_t *const queue, void *data, const size_t size, const size_t count)
队列对象初始化。
xf_err_t xf_task_queue_send(xf_task_queue_t *const queue, void *item, const xf_task_queue_mode_t pos)
队列发送数据。
@ XF_TASK_QUEUE_SEND_TO_BACK
#define XF_RETURN_VOID
Definition xf_check.h:47
#define XF_ASSERT(condition, retval, tag, format,...)
xfusion 断言宏(条件 不成立 时则输出日志后返回)。
Definition xf_check.h:150
#define BITS_SET0(var, bits_mask)
设置 32 位变量 var 的对应位掩码 bits_mask 为 1 的地方为 0。
#define BITS_SET1(var, bits_mask)
设置 32 位变量 var 的对应位掩码 bits_mask 为 1 的地方为 1。
#define BITS_CHECK(src, bits_mask)
检查变量 var 在 bits_mask 的位置上是否存在 1。
int32_t xf_err_t
整形错误类型。 错误码具体值见 xf_err_code_t.
Definition xf_err.h:69
@ XF_ERR_INVALID_ARG
Definition xf_err.h:46
@ XF_ERR_NOT_SUPPORTED
Definition xf_err.h:51
@ XF_OK
Definition xf_err.h:43
@ XF_ERR_BUSY
Definition xf_err.h:52
@ XF_ERR_TIMEOUT
Definition xf_err.h:53
static void xf_list_init(xf_list_t *list)
动态初始化链表.
Definition xf_list.h:97
static void xf_list_add_tail(xf_list_t *new_node, xf_list_t *head)
xf_list_add_tail - 在指定节点之前添加一个 new_node.
Definition xf_list.h:168
static void xf_list_del_init(xf_list_t *entry)
xf_list_del_init - 从链表中删除节点, 并重新初始化.
Definition xf_list.h:266
#define xf_list_for_each_entry_safe(pos, n, head, type, member)
list_for_each_entry_safe - 安全地迭代给定类型的链表,可删除链表节点。
Definition xf_list.h:876
#define xf_malloc(x)
Definition xf_stdlib.h:38
#define xf_free(x)
Definition xf_stdlib.h:39
#define xf_bzero(ptr, size)
Definition xf_string.h:43
static xf_osal_queue_t queue
Definition xf_main.c:35
ctask 的传入参数。
Definition xf_ctask.h:52
xf_list_t queue_node
Definition xf_ctask.c:31
xf_task_base_t base
Definition xf_ctask.c:27
xf_task_context_t context
Definition xf_ctask.c:29
xf_list_t receive_waiting
Definition xf_ctask.c:38
xf_task_manager_t manager
Definition xf_ctask.c:36
xf_task_queue_t queue
Definition xf_ctask.c:35
task 的父对象,保存了 task 的公共属性。
xf_task_time_t wake_up
xf_task_manager_t manager
消息队列对象结构体。
虚函数表,不在 base 对象实现,由子对象完成实现。
const xf_task_create_t constructor
双向链表结构体.
Definition xf_list.h:64
static void task(xf_task_t task)
Definition xf_main.c:45
static xf_task_time_t xf_ctask_update(xf_task_t task)
Definition xf_ctask.c:251
void xf_ctask_queue_delete(xf_ctask_queue_t queue)
Definition xf_ctask.c:116
static void xf_ctask_resume(xf_task_manager_t manager)
Definition xf_ctask.c:324
static const xf_task_vfunc_t _ctask_vfunc
Definition xf_ctask.c:54
void xf_ctask_vfunc_register(void)
Definition xf_ctask.c:63
static void xf_ctask_reset(xf_task_t task)
Definition xf_ctask.c:281
static void xf_ctask_yield(xf_task_manager_t manager)
Definition xf_ctask.c:310
static void xf_ctask_exec(xf_task_manager_t manager)
Definition xf_ctask.c:339
static void xf_task_context_entry(void *args)
Definition xf_ctask.c:296
static xf_task_t xf_ctask_constructor(xf_task_manager_t manager, xf_task_func_t func, void *func_arg, uint16_t priority, void *config)
Definition xf_ctask.c:225
struct _xf_ctask_queue_handle_t xf_ctask_queue_handle_t
struct _xf_ctask_handle_t xf_ctask_handle_t
#define TAG
Definition xf_ctask.c:22
有栈协程。
#define XF_LOGE(tag, format,...)
#define XF_LOGD(tag, format,...)
void xf_task_base_init(xf_task_base_t *task_base, xf_task_manager_t manager, xf_task_type_t type, uint16_t priority, xf_task_func_t func, void *arg)
task 初始化。
xf_err_t xf_task_base_set_state(xf_task_t task, xf_task_state_t state)
task 设置状态。
void xf_task_base_reset(xf_task_base_t *task_base)
重置 task base 部分内容
xf_err_t xf_task_vfunc_register(xf_task_type_t type, const xf_task_vfunc_t *vfunc)
task 的虚函数注册。
#define XF_TASK_SIGNAL_EVENT
#define XF_TASK_SIGNAL_TIMEOUT
#define XF_TASK_SIGNAL_READY
XF_TASK_TIME_TYPE xf_task_time_t
xf_task 时间戳类型。
xf_err_t xf_task_trigger(xf_task_t task)
任务触发。无论是否到达唤醒时间,都会触发。
void xf_task_delete(xf_task_t task)
任务删除函数。将任务加入销毁队列,并设置任务为删除态。
void(* xf_task_func_t)(xf_task_t task)
任务调用函数原型。
@ XF_TASK_STATE_DELETE
@ XF_TASK_STATE_RUNNING
xf_task_context_t * xf_task_manager_get_context(xf_task_manager_t manager)
xf_task_t xf_task_manager_get_current_task(xf_task_manager_t manager)
获取管理器运行的任务。
void * xf_task_manager_t
任务管理器句柄。
void * xf_task_t
任务句柄。
xf_task_time_t xf_task_get_ticks(void)
int32_t xf_task_ticks_to_msec(int32_t ticks)
void xf_task_context_swap(xf_task_manager_t manager, void *old_context, void *new_context)
int32_t xf_task_msec_to_ticks(int32_t msec)
void xf_task_context_create(xf_task_manager_t manager, xf_context_func_t context_entry, void *context, void *stack, size_t stack_size)
XF_TASK_CONTEXT_TYPE xf_task_context_t
如果开启上下文, 旧必须设置 XF_TASK_CONTEXT_TYPE 的类型。