XFusion API v1.3.0
载入中...
搜索中...
未找到
xf_task_manager.c
浏览该文件的文档.
1
12/* ==================== [Includes] ========================================== */
13
15#include "../port/xf_task_port_internal.h"
16#include "xf_task_manager.h"
17#include "xf_task_base.h"
18#include "xf_utils.h"
19
20/* ==================== [Defines] =========================================== */
21
22#define TAG "manager"
23
24/* ==================== [Typedefs] ========================================== */
25
41
42/* ==================== [Static Prototypes] ================================= */
43
44static inline void xf_task_run(xf_task_base_t *task);
45static inline void xf_task_update_timeout(xf_task_base_t *task);
46
47/* ==================== [Static Variables] ================================== */
48
49/* ==================== [Macros] ============================================ */
50
51/* ==================== [Global Functions] ================================== */
52
54{
56 XF_ASSERT(manager, NULL, TAG, "memory alloc failed!");
57
58 manager->current_task = NULL;
59 manager->urgent_task = NULL;
60 manager->on_idle = on_idle;
61
62 for (size_t i = 0; i < XF_TASK_PRIORITY_LEVELS; i++) {
63 xf_list_init(&manager->ready_list[i]);
64 }
65 xf_list_init(&manager->blocked_list);
66 xf_list_init(&manager->destroy_list);
67 xf_list_init(&manager->suspend_list);
68#if XF_TASK_HUNGER_IS_ENABLE
69 xf_list_init(&manager->hunger_list);
70#endif // XF_TASK_HUNGER_IS_ENABLE
71
72 return (xf_task_manager_t)manager;
73}
74
76{
77 XF_ASSERT(manager, XF_ERR_INVALID_ARG, TAG, "manager must not be NULL!");
78 XF_ASSERT(on_idle, XF_ERR_INVALID_ARG, TAG, "on_idle must not be NULL!");
79
80 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
81 manager_handle->on_idle = on_idle;
82 return XF_OK;
83}
84
86{
87 XF_ASSERT(manager, XF_RETURN_VOID, TAG, "manager must not be NULL!");
88 xf_free(manager);
89}
90
92{
93 XF_ASSERT(manager, XF_RETURN_VOID, TAG, "manager_handle must not be NULL");
94
95 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
96 volatile uint32_t index = 0;
97 // 阻塞的最小时间,即是空闲的最大时间
98 volatile int32_t max_idle_ms = INT32_MAX;
99 // 保存ticks用于后续校准最大空闲
100 volatile uint32_t idle_time_ticks = 0;
101 volatile bool is_get_func = false;
102 xf_task_base_t *task, *_task;
103
104 // 阻塞任务队列处理
105 xf_list_for_each_entry_safe(task, _task, &manager_handle->blocked_list, xf_task_base_t, node) {
106 // 更新信号
107 uint32_t time_ticks = task->vfunc->update(task);
108
109 // 检查信号,如果符合则加入就绪
110 if (BITS_CHECK(task->signal, XF_TASK_SIGNAL_READY)) {
111 xf_list_del_init(&task->node);
112 xf_task_base_set_state(task, XF_TASK_STATE_READY); // 设置为就绪态
113 xf_list_add_tail(&task->node, &manager_handle->ready_list[task->priority]);
115#if XF_TASK_HUNGER_IS_ENABLE
117 xf_list_add_tail(&task->hunger_node, &manager_handle->hunger_list);
118 }
119#endif // XF_TASK_HUNGER_IS_ENABLE
120 }
121
122 // 事件触发任务,这里始终等于0,不会被计算进入
123 // 计算阻塞任务中最小时间,如果进入空闲,则这里的时间是空闲任务最大时间
124 if (task->delay == 0 || task->timeout > 0 || -task->timeout > max_idle_ms || task->state != XF_TASK_STATE_BLOCKED) {
125 continue;
126 }
127 max_idle_ms = -task->timeout;
128 idle_time_ticks = time_ticks;
129 }
130
131 // 如果有紧急任务则优先执行紧急任务,并跳过后续调度
132 if (NULL != manager_handle->urgent_task) {
133 task = (xf_task_base_t *)manager_handle->urgent_task;
134 manager_handle->urgent_task = NULL;
136 return;
137 }
138
139 // 就绪任务队列处理
140 // 这里决定了它的优先级数值越小优先级越高
141 for (index = 0; index < XF_TASK_PRIORITY_LEVELS; index++) {
142 if (xf_list_empty(&manager_handle->ready_list[index])) {
143 continue;
144 }
145 // 选取相对最高优先级的任务作为执行任务
146 if (false == is_get_func) {
147 task = xf_list_first_entry(&manager_handle->ready_list[index], xf_task_base_t, node);
149 is_get_func = true;
150 break;
151 }
152 }
153
154 // 上述循环正常退出,则说明没有就绪任务,运行空闲任务
155 if (false == is_get_func) {
156 // 空闲时间,处理一下需要删除的任务
157 xf_list_for_each_entry_safe(task, _task, &manager_handle->destroy_list, xf_task_base_t, node) {
158 xf_list_del_init(&task->node);
159 task->delete (task);
160 }
161 // 进一步修正空闲时间
163 max_idle_ms -= xf_task_ticks_to_msec(ticks - idle_time_ticks);
164 max_idle_ms = max_idle_ms < 0 ? 0 : max_idle_ms;
165 // 执行空闲回调
166 if (manager_handle->on_idle != NULL) {
167 manager_handle->on_idle(max_idle_ms);
168 }
169 }
170#if XF_TASK_HUNGER_IS_ENABLE
171 else {
172 // 对事件触发任务一视同仁
173 // 对感受饥饿的任务进行临时优先级跳跃
174 xf_list_for_each_entry_safe(task, _task, &manager_handle->hunger_list, xf_task_base_t, hunger_node) {
176
177 // 计算爬升等级
178 uint32_t level = task->timeout / task->hunger_time;
179
180 // 限制爬升等级
181 int priority = (int)task->priority - (int)level;
182 if (priority < 0) {
183 priority = 0;
184 }
185
186 // 重置其优先级
187 xf_list_del_init(&task->node);
188 xf_list_add(&task->node, &manager_handle->ready_list[priority]);
189 }
190 }
191#endif // XF_TASK_HUNGER_IS_ENABLE
192
193}
194
196{
197 XF_ASSERT(manager, NULL, TAG, "manager must not be NULL!");
198
199 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
200
201 return manager_handle->current_task;
202}
203
205{
206 XF_ASSERT(manager, XF_ERR_INVALID_ARG, TAG, "manager must not be NULL!");
207
208 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
209
210 xf_task_base_t *task_base = task;
211
212 xf_list_del_init(&task_base->node);
213
215 xf_list_add_tail(&task_base->node, &manager_handle->ready_list[task_base->priority]);
216
217 return XF_OK;
218}
219
221{
222 XF_ASSERT(manager, XF_ERR_INVALID_ARG, TAG, "manager must not be NULL!");
223
224 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
225
226 xf_task_base_t *task_base = task;
227
228 xf_list_del_init(&task_base->node);
229
231 xf_list_add_tail(&task_base->node, &manager_handle->suspend_list);
232
233 return XF_OK;
234}
235
237{
238 XF_ASSERT(manager, XF_ERR_INVALID_ARG, TAG, "manager must not be NULL!");
239
240 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
241
242 xf_task_base_t *task_base = task;
243
244 xf_list_del_init(&task_base->node);
245
247 xf_list_add_tail(&task_base->node, &manager_handle->destroy_list);
248
249 return XF_OK;
250}
251
253{
254 XF_ASSERT(manager, XF_ERR_INVALID_ARG, TAG, "manager must not be NULL!");
255
256 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
257
258 xf_task_base_t *task_base = task;
259
260 xf_list_del_init(&task_base->node);
261
263 xf_list_add_tail(&task_base->node, &manager_handle->blocked_list);
264
265 return XF_OK;
266}
267
268#if XF_TASK_CONTEXT_IS_ENABLE
270{
271 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
272
273 return &manager_handle->context;
274}
275#endif // XF_TASK_CONTEXT_IS_ENABLE
276
278{
279 XF_ASSERT(manager, XF_ERR_INVALID_ARG, TAG, "manager must not be NULL");
280 XF_ASSERT(task, XF_ERR_INVALID_ARG, TAG, "task must not be NULL");
281
282 xf_task_manager_handle_t *manager_handle = (xf_task_manager_handle_t *)manager;
283
284 if (manager_handle->urgent_task != NULL && !force) {
285 return XF_ERR_BUSY;
286 }
287
288 manager_handle->urgent_task = task;
290
291 return XF_OK;
292}
293
294/* ==================== [Static Functions] ================================== */
295
296static inline void xf_task_run(xf_task_base_t *task)
297{
299
300#if XF_TASK_HUNGER_IS_ENABLE
302 xf_list_del_init(&task->hunger_node);
303 }
304#endif // XF_TASK_HUNGER_IS_ENABLE
305
306 xf_list_del_init(&task->node); // 从原有链表中脱离
307 manager->current_task = task; // 放入当前执行的任务
309 task->vfunc->exec(manager); // 执行任务
310 manager->current_task = NULL;
311
312 // 如果设置成功,则进入阻塞状态。如果设置不成功(删除或挂起)则不管它
314 xf_list_add_tail(&task->node, &manager->blocked_list);
315 }
316}
317
319{
320 xf_task_time_t timeout = xf_task_get_ticks() - task->wake_up;
321 task->timeout = xf_task_ticks_to_msec(timeout);
322}
#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_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_OK
Definition xf_err.h:43
@ XF_ERR_BUSY
Definition xf_err.h:52
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
static int xf_list_empty(const xf_list_t *head)
xf_list_empty - 测试链表是否为空.
Definition xf_list.h:342
#define xf_list_first_entry(ptr, type, member)
xf_list_first_entry - 获取链表中的第一个元素.
Definition xf_list.h:617
#define xf_list_for_each_entry_safe(pos, n, head, type, member)
list_for_each_entry_safe - 安全地迭代给定类型的链表,可删除链表节点。
Definition xf_list.h:876
static void xf_list_add(xf_list_t *new_node, xf_list_t *head)
xf_list_add - 在指定节点之后添加一个 new_node.
Definition xf_list.h:145
#define xf_malloc(x)
Definition xf_stdlib.h:38
#define xf_free(x)
Definition xf_stdlib.h:39
task 的父对象,保存了 task 的公共属性。
const xf_task_vfunc_t * vfunc
xf_task_on_idle_t on_idle
xf_task_context_t context
xf_list_t ready_list[XF_TASK_PRIORITY_LEVELS]
const xf_task_update_t update
双向链表结构体.
Definition xf_list.h:64
static void task(xf_task_t task)
Definition xf_main.c:45
xf_err_t xf_task_base_set_state(xf_task_t task, xf_task_state_t state)
task 设置状态。
本头文件外界无法调用,manager 基于 base 进行调度。 开放部分在 xf_task_kernel.h .
#define XF_TASK_SIGNAL_READY
#define XF_TASK_FALG_FEEL_HUNGERY
外部设置的标志位,内部只会读取不会设置.
XF_TASK_TIME_TYPE xf_task_time_t
xf_task 时间戳类型。
@ XF_TASK_STATE_SUSPEND
@ XF_TASK_STATE_DELETE
@ XF_TASK_STATE_READY
@ XF_TASK_STATE_BLOCKED
xf_task 内核配置(仅 xf_task kernel 内部使用)。
#define XF_TASK_PRIORITY_LEVELS
配置任务最高优先级,1 ~ 1024 之间。
xf_task_context_t * xf_task_manager_get_context(xf_task_manager_t manager)
struct _xf_task_manager_handle_t xf_task_manager_handle_t
xf_err_t xf_task_manager_set_idle(xf_task_manager_t manager, xf_task_on_idle_t on_idle)
设置 manager 的空闲回调函数
static void xf_task_update_timeout(xf_task_base_t *task)
void xf_task_manager_delete(xf_task_manager_t manager)
xf_err_t xf_task_manager_task_blocked(xf_task_manager_t manager, xf_task_t task)
设置当前任务为阻塞。
xf_err_t xf_task_manager_task_suspend(xf_task_manager_t manager, xf_task_t task)
设置当前任务为挂起。
void xf_task_manager_run(xf_task_manager_t manager)
开始启动任务管理器调度任务。
xf_err_t xf_task_set_urgent_task_with_manager(xf_task_manager_t manager, xf_task_t task, bool force)
将任务设置为紧急任务,下次调度立即执行。
xf_task_manager_t xf_task_manager_create(xf_task_on_idle_t on_idle)
创建任务管理器。
xf_err_t xf_task_manager_task_ready(xf_task_manager_t manager, xf_task_t task)
设置当前任务为就绪。
static void xf_task_run(xf_task_base_t *task)
xf_err_t xf_task_manager_task_destory(xf_task_manager_t manager, xf_task_t task)
设置当前任务为销毁。
xf_task_t xf_task_manager_get_current_task(xf_task_manager_t manager)
获取管理器运行的任务。
#define TAG
任务管理器。
void * xf_task_manager_t
任务管理器句柄。
void * xf_task_t
任务句柄。
void(* xf_task_on_idle_t)(unsigned long int max_idle_ms)
空闲任务回调函数原型。
xf_task_time_t xf_task_get_ticks(void)
int32_t xf_task_ticks_to_msec(int32_t ticks)
XF_TASK_CONTEXT_TYPE xf_task_context_t
如果开启上下文, 旧必须设置 XF_TASK_CONTEXT_TYPE 的类型。