add API (tos_task_create_dyn & tos_task_walkthru & tos_task_curr_task_get)

tos_task_create_dyn: create task with dynamic allocated task handler and stack
tos_task_walkthru: API to walk through the statistic list of all the existing task
tos_task_curr_task_get: get current running task handler
This commit is contained in:
daishengdong
2019-10-23 21:22:13 +08:00
parent c4d928a42b
commit 06cae326a2
58 changed files with 518 additions and 84 deletions

View File

@@ -23,6 +23,10 @@ __STATIC_INLINE__ void task_reset(k_task_t *task)
knl_object_deinit(&task->knl_obj);
#endif
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
tos_list_init(&task->dead_list);
#endif
tos_list_init(&task->stat_list);
tos_list_init(&task->tick_list);
tos_list_init(&task->pend_list);
@@ -102,6 +106,8 @@ __API__ k_err_t tos_task_create(k_task_t *task,
}
task_reset(task);
tos_list_add(&task->stat_list, &k_stat_list);
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
knl_object_init(&task->knl_obj, KNL_OBJ_TYPE_TASK);
#endif
@@ -136,30 +142,14 @@ __API__ k_err_t tos_task_create(k_task_t *task,
return K_ERR_NONE;
}
__API__ k_err_t tos_task_destroy(k_task_t *task)
__STATIC__ k_err_t task_do_destroy(k_task_t *task)
{
TOS_CPU_CPSR_ALLOC();
TOS_IN_IRQ_CHECK();
if (unlikely(!task)) {
task = k_curr_task;
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
return K_ERR_OBJ_INVALID;
}
#endif
if (knl_is_idle(task)) {
return K_ERR_TASK_DESTROY_IDLE;
}
if (knl_is_self(task) && knl_is_sched_locked()) {
return K_ERR_SCHED_LOCKED;
}
TOS_CPU_INT_DISABLE();
#if TOS_CFG_MUTEX_EN > 0u
@@ -179,7 +169,9 @@ __API__ k_err_t tos_task_destroy(k_task_t *task)
pend_list_remove(task);
}
tos_list_del(&task->stat_list);
task_reset(task);
task_state_set_deleted(task);
TOS_CPU_INT_ENABLE();
@@ -188,6 +180,147 @@ __API__ k_err_t tos_task_destroy(k_task_t *task)
return K_ERR_NONE;
}
__API__ k_err_t tos_task_destroy(k_task_t *task)
{
TOS_IN_IRQ_CHECK();
if (unlikely(!task)) {
task = k_curr_task;
}
if (knl_is_self(task) && knl_is_sched_locked()) {
return K_ERR_SCHED_LOCKED;
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
return K_ERR_OBJ_INVALID;
}
#endif
return task_do_destroy(task);
}
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
__API__ k_err_t tos_task_create_dyn(k_task_t **task,
char *name,
k_task_entry_t entry,
void *arg,
k_prio_t prio,
size_t stk_size,
k_timeslice_t timeslice)
{
k_err_t err;
k_task_t *the_task;
k_stack_t *stk_base;
TOS_IN_IRQ_CHECK();
TOS_PTR_SANITY_CHECK(task);
TOS_PTR_SANITY_CHECK(entry);
if (unlikely(stk_size < sizeof(cpu_context_t))) {
return K_ERR_TASK_STK_SIZE_INVALID;
}
if (unlikely(prio == K_TASK_PRIO_IDLE)) {
return K_ERR_TASK_PRIO_INVALID;
}
if (unlikely(prio > K_TASK_PRIO_IDLE)) {
return K_ERR_TASK_PRIO_INVALID;
}
the_task = tos_mmheap_alloc(sizeof(k_task_t));
if (!the_task) {
return K_ERR_TASK_OUT_OF_MEMORY;
}
stk_base = tos_mmheap_aligned_alloc(stk_size, sizeof(cpu_addr_t));
if (!stk_base) {
tos_mmheap_free(the_task);
return K_ERR_TASK_OUT_OF_MEMORY;
}
err = tos_task_create(the_task, name, entry, arg, prio, stk_base, stk_size, timeslice);
if (err != K_ERR_NONE) {
tos_mmheap_free(stk_base);
tos_mmheap_free(the_task);
return err;
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
knl_object_init(&the_task->knl_obj, KNL_OBJ_TYPE_TASK_DYN);
#endif
*task = the_task;
return K_ERR_NONE;
}
__API__ k_err_t tos_task_destroy_dyn(k_task_t *task)
{
k_err_t err;
TOS_IN_IRQ_CHECK();
if (unlikely(!task)) {
task = k_curr_task;
}
if (knl_is_self(task) && knl_is_sched_locked()) {
return K_ERR_SCHED_LOCKED;
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
tos_knl_sched_lock();
err = task_do_destroy(task);
if (err != K_ERR_NONE) {
tos_knl_sched_unlock();
return err;
}
if (knl_is_self(task)) { // we are destroying ourself
// in this situation, we cannot just free ourself's task stack because we are using it
// we count on the idle task to free the memory
tos_list_add(&task->dead_list, &k_dead_task_list);
} else {
tos_mmheap_free(task->stk_base);
tos_mmheap_free(task);
}
tos_knl_sched_unlock();
return K_ERR_NONE;
}
__KERNEL__ void task_free_all(void)
{
TOS_CPU_CPSR_ALLOC();
k_task_t *task;
k_list_t *curr, *next;
TOS_CPU_INT_DISABLE();
TOS_LIST_FOR_EACH_SAFE(curr, next, &k_dead_task_list) {
task = TOS_LIST_ENTRY(curr, k_task_t, dead_list);
tos_list_del(&task->dead_list);
tos_mmheap_free(task->stk_base);
tos_mmheap_free(task);
}
TOS_CPU_INT_ENABLE();
}
#endif
__API__ void tos_task_yield(void)
{
TOS_CPU_CPSR_ALLOC();
@@ -216,7 +349,8 @@ __API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new)
TOS_IN_IRQ_CHECK();
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
@@ -278,7 +412,8 @@ __API__ k_err_t tos_task_suspend(k_task_t *task)
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
@@ -311,7 +446,8 @@ __API__ k_err_t tos_task_resume(k_task_t *task)
TOS_PTR_SANITY_CHECK(task);
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
@@ -378,7 +514,8 @@ __API__ k_err_t tos_task_delay_abort(k_task_t *task)
TOS_IN_IRQ_CHECK();
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
@@ -404,6 +541,45 @@ __API__ k_err_t tos_task_delay_abort(k_task_t *task)
return K_ERR_NONE;
}
__API__ k_task_t *tos_task_curr_task_get(void)
{
TOS_CPU_CPSR_ALLOC();
k_task_t *curr_task = K_NULL;
TOS_CPU_INT_DISABLE();
if (likely(tos_knl_is_running())) {
curr_task = k_curr_task;
}
TOS_CPU_INT_ENABLE();
return curr_task;
}
__API__ void tos_task_walkthru(k_task_walker walker)
{
TOS_CPU_CPSR_ALLOC();
k_task_t *task;
k_list_t *curr;
if (!walker) {
return;
}
TOS_CPU_INT_DISABLE();
TOS_LIST_FOR_EACH(curr, &k_stat_list) {
task = TOS_LIST_ENTRY(curr, k_task_t, stat_list);
walker(task);
}
TOS_CPU_INT_ENABLE();
}
__DEBUG__ void tos_task_info_display(void)
{
tos_task_walkthru(task_default_walker);
}
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
__API__ k_err_t tos_task_stack_draught_depth(k_task_t *task, int *depth)
@@ -418,7 +594,8 @@ __API__ k_err_t tos_task_stack_draught_depth(k_task_t *task, int *depth)
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif