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:
@@ -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
|
||||
|
Reference in New Issue
Block a user