Add schedule node midway

This commit is contained in:
TXuian
2024-12-24 01:01:54 +08:00
parent 7639937678
commit 21304531a5
21 changed files with 269 additions and 237 deletions
+106 -48
View File
@@ -33,65 +33,123 @@ Modification:
struct Thread* max_priority_runnable_task(void)
{
static struct Thread* task = NULL;
static int priority = 0;
// static int priority = 0;
priority = __builtin_ffs(ready_task_priority) - 1;
if (priority > 31 || priority < 0) {
return NULL;
}
// priority = __builtin_ffs(ready_task_priority) - 1;
// if (priority > 31 || priority < 0) {
// return NULL;
// }
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node)
{
assert(task != NULL);
if (task->state == READY && !task->dead) {
// found a runnable task, stop this look up
return task;
} else if (task->dead && task->state != RUNNING) {
// DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node)
// {
// assert(task != NULL);
// if (task->state == READY && !task->dead) {
// // found a runnable task, stop this look up
// return task;
// } else if (task->dead && task->state != RUNNING) {
struct TaskLifecycleOperations* tlo = GetSysObject(struct TaskLifecycleOperations, &xizi_task_manager.task_lifecycle_ops_tag);
tlo->free_pcb(task);
return NULL;
}
// struct TaskLifecycleOperations* tlo = GetSysObject(struct TaskLifecycleOperations, &xizi_task_manager.task_lifecycle_ops_tag);
// tlo->free_pcb(task);
// return NULL;
// }
// }
if (!rbt_is_empty(&g_scheduler.snode_state_pool[READY])) {
return ((struct ScheduleNode*)(g_scheduler.snode_state_pool[READY].root->data))->pthd;
}
return NULL;
}
struct Thread* round_robin_runnable_task(uint32_t priority)
#include "multicores.h"
#include "rbtree.h"
#include "task.h"
bool init_schedule_node(struct ScheduleNode* snode, struct Thread* bind_thd)
{
struct Thread* task = NULL;
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node)
{
if (task->state == READY && !task->dead) {
// found a runnable task, stop this look up
return task;
} else if (task->dead && task->state != RUNNING) {
struct TaskLifecycleOperations* tlo = GetSysObject(struct TaskLifecycleOperations, &xizi_task_manager.task_lifecycle_ops_tag);
tlo->free_pcb(task);
return NULL;
}
snode->pthd = bind_thd;
snode->snode_id = bind_thd->tid;
snode->sched_context.remain_tick = 0;
snode->sleep_context.remain_ms = 0;
snode->state = INIT;
if (RBTTREE_INSERT_SECC != rbt_insert(&g_scheduler.snode_state_pool[INIT], //
snode->snode_id, (void*)snode)) {
return false;
}
return NULL;
return true;
}
/* recover task priority */
void recover_priority(void)
bool task_trans_sched_state(struct ScheduleNode* snode, RbtTree* from_pool, RbtTree* to_pool, enum ThreadState target_state)
{
struct Thread* task = NULL;
for (int i = 1; i < TASK_MAX_PRIORITY; i++) {
if (i == TASK_DEFAULT_PRIORITY)
continue;
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[i], node)
{
if (!IS_DOUBLE_LIST_EMPTY(&task->node)) {
// DEBUG("%s priority recover\n", task->name);
task->priority = TASK_DEFAULT_PRIORITY;
doubleListDel(&task->node);
doubleListAddOnBack(&task->node, &xizi_task_manager.task_list_head[task->priority]);
i--;
break;
}
}
assert(snode->snode_id != UNINIT_SNODE_ID && snode->pthd != NULL);
if (RBTTREE_DELETE_SUCC != rbt_delete(from_pool, snode->snode_id)) {
DEBUG("Thread %d not in from schedule pool\n", snode->pthd->tid);
return false;
}
if (RBTTREE_INSERT_SECC != rbt_insert(to_pool, snode->snode_id, (void*)snode)) {
DEBUG("Thread %d trans state failed\n", snode->pthd->tid);
return false;
}
snode->state = target_state;
return true;
}
void task_dead(struct Thread* thd)
{
assert(thd != NULL);
struct ScheduleNode* snode = &thd->snode;
enum ThreadState thd_cur_state = snode->state;
assert(snode->state == READY);
bool trans_res = task_trans_sched_state(snode, //
&g_scheduler.snode_state_pool[READY], //
&g_scheduler.snode_state_pool[DEAD], DEAD);
assert(trans_res = true);
return;
}
void task_block(struct Thread* thd)
{
assert(thd != NULL);
struct ScheduleNode* snode = &thd->snode;
enum ThreadState thd_cur_state = snode->state;
assert(thd_cur_state != RUNNING);
bool trans_res = task_trans_sched_state(snode, //
&g_scheduler.snode_state_pool[thd_cur_state], //
&g_scheduler.snode_state_pool[BLOCKED], BLOCKED);
assert(trans_res = true);
return;
}
void task_into_ready(struct Thread* thd)
{
assert(thd != NULL);
struct ScheduleNode* snode = &thd->snode;
enum ThreadState thd_cur_state = snode->state;
bool trans_res = task_trans_sched_state(snode, //
&g_scheduler.snode_state_pool[thd_cur_state], //
&g_scheduler.snode_state_pool[READY], READY);
snode->sched_context.remain_tick = TASK_CLOCK_TICK;
assert(trans_res = true);
return;
}
void task_yield(struct Thread* thd)
{
assert(thd != NULL);
struct ScheduleNode* snode = &thd->snode;
enum ThreadState thd_cur_state = snode->state;
assert(thd == cur_cpu()->task && thd_cur_state == RUNNING);
cur_cpu()->task = NULL;
bool trans_res = task_trans_sched_state(snode, //
&g_scheduler.snode_state_pool[thd_cur_state], //
&g_scheduler.snode_state_pool[READY], READY);
assert(trans_res = true);
return;
}