133 lines
3.4 KiB
C
133 lines
3.4 KiB
C
/*
|
|
* Copyright (c) 2020 AIIT XUOS Lab
|
|
* XiUOS is licensed under Mulan PSL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PSL v2 for more details.
|
|
*/
|
|
|
|
/**
|
|
* @file: linklist.c
|
|
* @brief: suspend and wakeup function of task
|
|
* @version: 1.0
|
|
* @author: AIIT XUOS Lab
|
|
* @date: 2020/3/15
|
|
*
|
|
*/
|
|
|
|
#include <xiuos.h>
|
|
|
|
/**
|
|
* a task will be suspended to a pend list
|
|
*
|
|
* @param list suspend task list
|
|
* @param task the task descriptor need to be suspended
|
|
* @param flag suspend flag
|
|
*
|
|
*/
|
|
x_err_t LinklistSuspend(DoubleLinklistType *list,
|
|
struct TaskDescriptor *task,
|
|
uint8 flag)
|
|
{
|
|
int32 ret = EOK;
|
|
x_ubase lock = 0;
|
|
DoubleLinklistType *node = NONE;
|
|
DoubleLinklistType *tail = NONE;
|
|
struct TaskDescriptor *tmp_task = NONE;
|
|
|
|
NULL_PARAM_CHECK(list);
|
|
NULL_PARAM_CHECK(task);
|
|
|
|
lock = CriticalAreaLock();
|
|
|
|
SuspendKTask(task->id.id);
|
|
switch (flag)
|
|
{
|
|
case LINKLIST_FLAG_FIFO:
|
|
DoubleLinkListInsertNodeBefore(list, &(task->task_dync_sched_member.sched_link));
|
|
break;
|
|
|
|
case LINKLIST_FLAG_PRIO:
|
|
DOUBLE_LINKLIST_FOR_EACH(node,list)
|
|
{
|
|
tmp_task = SYS_DOUBLE_LINKLIST_ENTRY(node, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
|
if (task->task_dync_sched_member.cur_prio < tmp_task->task_dync_sched_member.cur_prio)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if(node != list) {
|
|
DoubleLinkListInsertNodeBefore(&(tmp_task->task_dync_sched_member.sched_link), &(task->task_dync_sched_member.sched_link));
|
|
} else {
|
|
tail = list->node_prev;
|
|
DoubleLinkListInsertNodeAfter(tail,&(task->task_dync_sched_member.sched_link));
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ret = -EINVALED;
|
|
break;
|
|
}
|
|
CriticalAreaUnLock(lock);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* resume the first task in the suspend list
|
|
*
|
|
* @param list task list
|
|
*
|
|
*/
|
|
x_err_t LinklistResume(DoubleLinklistType *list)
|
|
{
|
|
x_ubase lock = 0;
|
|
struct TaskDescriptor *task = NONE;
|
|
|
|
NULL_PARAM_CHECK(list);
|
|
|
|
lock = CriticalAreaLock();
|
|
|
|
task = SYS_DOUBLE_LINKLIST_ENTRY(list->node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
|
SYS_KDEBUG_LOG(KDBG_IPC, ("resume task:%s\n", task->task_base_info.name));
|
|
|
|
KTaskWakeup(task->id.id);
|
|
|
|
CriticalAreaUnLock(lock);
|
|
|
|
return EOK;
|
|
}
|
|
|
|
/**
|
|
* wakeup all the task in the suspend list
|
|
*
|
|
* @param list task list
|
|
*
|
|
*/
|
|
x_err_t LinklistResumeAll(DoubleLinklistType *list)
|
|
{
|
|
x_ubase lock = 0;
|
|
struct TaskDescriptor *task = NONE;
|
|
DoubleLinklistType *node = NONE;
|
|
|
|
NULL_PARAM_CHECK(list);
|
|
|
|
lock = CriticalAreaLock();
|
|
for(;;) {
|
|
node = list->node_next;
|
|
if(node != list) {
|
|
task = SYS_DOUBLE_LINKLIST_ENTRY(node, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
|
task->exstatus = -ERROR;
|
|
KTaskWakeup(task->id.id);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
CriticalAreaUnLock(lock);
|
|
|
|
return EOK;
|
|
}
|