feat: support EDF
方案描述: 1、liteos_a调度框架支持EDF调度算法,默认优先调度EDF策略的任务 2、用户态musl_c库适配新增调度算法,同步修改相关接口以支持用户态创建EDF进程与线程 BREAKING CHANGE: support EDF对外变更描述: 以下接口支持SCHED_DEADLINE调度策略: pthread_attr_getschedparam pthread_attr_setschedparam pthread_getschedparam pthread_setschedparam pthread_create sched_getscheduler sched_getparam sched_setparam sched_setscheduler Close:#I6T3P3 Signed-off-by: zhangdengyu <zhangdengyu2@huawei.com> Change-Id: Ic9fe6896fcae42ae4ee7fe5dfb8e858a6ed19740
This commit is contained in:
parent
4ff66c7f40
commit
13f68dcf9c
7
Kconfig
7
Kconfig
|
@ -235,7 +235,12 @@ config SCHED_DEBUG
|
||||||
depends on DEBUG_VERSION
|
depends on DEBUG_VERSION
|
||||||
help
|
help
|
||||||
If you wish to build LiteOS with support for sched debug.
|
If you wish to build LiteOS with support for sched debug.
|
||||||
|
config SCHED_EDF_DEBUG
|
||||||
|
bool "Enable sched EDF debug Feature"
|
||||||
|
default n
|
||||||
|
depends on SCHED_DEBUG
|
||||||
|
help
|
||||||
|
If you wish to build LiteOS with support for sched debug.
|
||||||
config USER_INIT_DEBUG
|
config USER_INIT_DEBUG
|
||||||
bool "Enable user init Debug"
|
bool "Enable user init Debug"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -76,6 +76,7 @@ kernel_module(module_name) {
|
||||||
"mp/los_percpu.c",
|
"mp/los_percpu.c",
|
||||||
"mp/los_spinlock.c",
|
"mp/los_spinlock.c",
|
||||||
"om/los_err.c",
|
"om/los_err.c",
|
||||||
|
"sched/los_deadline.c",
|
||||||
"sched/los_idle.c",
|
"sched/los_idle.c",
|
||||||
"sched/los_priority.c",
|
"sched/los_priority.c",
|
||||||
"sched/los_sched.c",
|
"sched/los_sched.c",
|
||||||
|
|
|
@ -939,7 +939,37 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
|
INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param)
|
||||||
|
{
|
||||||
|
if (param == NULL) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((policy == LOS_SCHED_RR) || (isThread && (policy == LOS_SCHED_FIFO))) {
|
||||||
|
if ((param->priority < OS_PROCESS_PRIORITY_HIGHEST) ||
|
||||||
|
(param->priority > OS_PROCESS_PRIORITY_LOWEST)) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policy == LOS_SCHED_DEADLINE) {
|
||||||
|
if ((param->runTimeUs < OS_SCHED_EDF_MIN_RUNTIME) || (param->runTimeUs >= param->deadlineUs)) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
if ((param->deadlineUs < OS_SCHED_EDF_MIN_DEADLINE) || (param->deadlineUs > OS_SCHED_EDF_MAX_DEADLINE)) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
if (param->periodUs < param->deadlineUs) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC INLINE INT32 ProcessSchedulerParamCheck(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *param)
|
||||||
{
|
{
|
||||||
if (OS_PID_CHECK_INVALID(pid)) {
|
if (OS_PID_CHECK_INVALID(pid)) {
|
||||||
return LOS_EINVAL;
|
return LOS_EINVAL;
|
||||||
|
@ -949,19 +979,11 @@ STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 p
|
||||||
return LOS_EINVAL;
|
return LOS_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prio > OS_PROCESS_PRIORITY_LOWEST) {
|
return OsSchedulerParamCheck(policy, FALSE, param);
|
||||||
return LOS_EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (policy != LOS_SCHED_RR) {
|
|
||||||
return LOS_EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LOS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||||
STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 prio)
|
STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 policy, UINT16 prio)
|
||||||
{
|
{
|
||||||
LosProcessCB *runProcess = OsCurrProcessGet();
|
LosProcessCB *runProcess = OsCurrProcessGet();
|
||||||
|
|
||||||
|
@ -971,7 +993,7 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedPa
|
||||||
}
|
}
|
||||||
|
|
||||||
/* user mode process can reduce the priority of itself */
|
/* user mode process can reduce the priority of itself */
|
||||||
if ((runProcess->processID == processCB->processID) && (prio > param->basePrio)) {
|
if ((runProcess->processID == processCB->processID) && (policy == LOS_SCHED_RR) && (prio > param->basePrio)) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,12 +1005,13 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedPa
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
|
LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *schedParam)
|
||||||
{
|
{
|
||||||
SchedParam param = { 0 };
|
SchedParam param = { 0 };
|
||||||
|
BOOL needSched = FALSE;
|
||||||
UINT32 intSave;
|
UINT32 intSave;
|
||||||
|
|
||||||
INT32 ret = OsProcessSchedlerParamCheck(which, pid, prio, policy);
|
INT32 ret = ProcessSchedulerParamCheck(which, pid, policy, schedParam);
|
||||||
if (ret != LOS_OK) {
|
if (ret != LOS_OK) {
|
||||||
return -ret;
|
return -ret;
|
||||||
}
|
}
|
||||||
|
@ -996,22 +1019,45 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio
|
||||||
LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
|
LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
|
||||||
SCHEDULER_LOCK(intSave);
|
SCHEDULER_LOCK(intSave);
|
||||||
if (OsProcessIsInactive(processCB)) {
|
if (OsProcessIsInactive(processCB)) {
|
||||||
ret = LOS_ESRCH;
|
SCHEDULER_UNLOCK(intSave);
|
||||||
goto EXIT;
|
return -LOS_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
|
||||||
if (!OsProcessCapPermitCheck(processCB, ¶m, prio)) {
|
|
||||||
ret = LOS_EPERM;
|
|
||||||
goto EXIT;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LosTaskCB *taskCB = processCB->threadGroup;
|
LosTaskCB *taskCB = processCB->threadGroup;
|
||||||
taskCB->ops->schedParamGet(taskCB, ¶m);
|
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||||
param.basePrio = prio;
|
|
||||||
|
|
||||||
BOOL needSched = taskCB->ops->schedParamModify(taskCB, ¶m);
|
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||||
|
if (!OsProcessCapPermitCheck(processCB, ¶m, policy, schedParam->priority)) {
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
return -LOS_EPERM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (param.policy != policy) {
|
||||||
|
if (policy == LOS_SCHED_DEADLINE) { /* HPF -> EDF */
|
||||||
|
if (processCB->threadNumber > 1) {
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
return -LOS_EPERM;
|
||||||
|
}
|
||||||
|
OsSchedParamInit(taskCB, policy, NULL, schedParam);
|
||||||
|
needSched = TRUE;
|
||||||
|
goto TO_SCHED;
|
||||||
|
} else if (param.policy == LOS_SCHED_DEADLINE) { /* EDF -> HPF */
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
return -LOS_EPERM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policy == LOS_SCHED_DEADLINE) {
|
||||||
|
param.runTimeUs = schedParam->runTimeUs;
|
||||||
|
param.deadlineUs = schedParam->deadlineUs;
|
||||||
|
param.periodUs = schedParam->periodUs;
|
||||||
|
} else {
|
||||||
|
param.basePrio = schedParam->priority;
|
||||||
|
}
|
||||||
|
needSched = taskCB->ops->schedParamModify(taskCB, ¶m);
|
||||||
|
|
||||||
|
TO_SCHED:
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
||||||
LOS_MpSchedule(OS_MP_CPU_ALL);
|
LOS_MpSchedule(OS_MP_CPU_ALL);
|
||||||
|
@ -1019,25 +1065,26 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio
|
||||||
LOS_Schedule();
|
LOS_Schedule();
|
||||||
}
|
}
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
|
|
||||||
EXIT:
|
|
||||||
SCHEDULER_UNLOCK(intSave);
|
|
||||||
return -ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, UINT16 prio)
|
LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, const LosSchedParam *schedParam)
|
||||||
{
|
{
|
||||||
return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, policy);
|
return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, policy, schedParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid)
|
LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSchedParam *schedParam)
|
||||||
{
|
{
|
||||||
UINT32 intSave;
|
UINT32 intSave;
|
||||||
|
SchedParam param = { 0 };
|
||||||
|
|
||||||
if (OS_PID_CHECK_INVALID(pid)) {
|
if (OS_PID_CHECK_INVALID(pid)) {
|
||||||
return -LOS_EINVAL;
|
return -LOS_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((policy == NULL) && (schedParam == NULL)) {
|
||||||
|
return -LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
SCHEDULER_LOCK(intSave);
|
SCHEDULER_LOCK(intSave);
|
||||||
LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
|
LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
|
||||||
if (OsProcessIsUnused(processCB)) {
|
if (OsProcessIsUnused(processCB)) {
|
||||||
|
@ -1045,14 +1092,48 @@ LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid)
|
||||||
return -LOS_ESRCH;
|
return -LOS_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LosTaskCB *taskCB = processCB->threadGroup;
|
||||||
|
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
||||||
return LOS_SCHED_RR;
|
if (policy != NULL) {
|
||||||
|
if (param.policy == LOS_SCHED_FIFO) {
|
||||||
|
*policy = LOS_SCHED_RR;
|
||||||
|
} else {
|
||||||
|
*policy = param.policy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schedParam != NULL) {
|
||||||
|
if (param.policy == LOS_SCHED_DEADLINE) {
|
||||||
|
schedParam->runTimeUs = param.runTimeUs;
|
||||||
|
schedParam->deadlineUs = param.deadlineUs;
|
||||||
|
schedParam->periodUs = param.periodUs;
|
||||||
|
} else {
|
||||||
|
schedParam->priority = param.basePrio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LOS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio)
|
LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio)
|
||||||
{
|
{
|
||||||
return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, LOS_GetProcessScheduler(pid));
|
INT32 ret;
|
||||||
|
INT32 policy;
|
||||||
|
LosSchedParam param = {
|
||||||
|
.priority = prio,
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = LOS_GetProcessScheduler(pid, &policy, NULL);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policy == LOS_SCHED_DEADLINE) {
|
||||||
|
return -LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, (UINT16)policy, ¶m);
|
||||||
}
|
}
|
||||||
|
|
||||||
LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
|
LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
|
||||||
|
@ -1079,6 +1160,11 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
|
||||||
LosTaskCB *taskCB = processCB->threadGroup;
|
LosTaskCB *taskCB = processCB->threadGroup;
|
||||||
taskCB->ops->schedParamGet(taskCB, ¶m);
|
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||||
|
|
||||||
|
if (param.policy == LOS_SCHED_DEADLINE) {
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
return -LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
return param.basePrio;
|
return param.basePrio;
|
||||||
}
|
}
|
||||||
|
@ -1850,6 +1936,38 @@ STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC VOID GetCopyTaskParam(LosProcessCB *childProcessCB, UINTPTR entry, UINT32 size,
|
||||||
|
TSK_INIT_PARAM_S *taskParam, SchedParam *param)
|
||||||
|
{
|
||||||
|
UINT32 intSave;
|
||||||
|
LosTaskCB *runTask = OsCurrTaskGet();
|
||||||
|
|
||||||
|
SCHEDULER_LOCK(intSave);
|
||||||
|
if (OsProcessIsUserMode(childProcessCB)) {
|
||||||
|
taskParam->pfnTaskEntry = runTask->taskEntry;
|
||||||
|
taskParam->uwStackSize = runTask->stackSize;
|
||||||
|
taskParam->userParam.userArea = runTask->userArea;
|
||||||
|
taskParam->userParam.userMapBase = runTask->userMapBase;
|
||||||
|
taskParam->userParam.userMapSize = runTask->userMapSize;
|
||||||
|
} else {
|
||||||
|
taskParam->pfnTaskEntry = (TSK_ENTRY_FUNC)entry;
|
||||||
|
taskParam->uwStackSize = size;
|
||||||
|
}
|
||||||
|
if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
|
||||||
|
taskParam->uwResved = LOS_TASK_ATTR_JOINABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
runTask->ops->schedParamGet(runTask, param);
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
||||||
|
taskParam->policy = param->policy;
|
||||||
|
taskParam->runTimeUs = param->runTimeUs;
|
||||||
|
taskParam->deadlineUs = param->deadlineUs;
|
||||||
|
taskParam->periodUs = param->periodUs;
|
||||||
|
taskParam->usTaskPrio = param->priority;
|
||||||
|
taskParam->processID = (UINTPTR)childProcessCB;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size)
|
STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size)
|
||||||
{
|
{
|
||||||
LosTaskCB *runTask = OsCurrTaskGet();
|
LosTaskCB *runTask = OsCurrTaskGet();
|
||||||
|
@ -1857,28 +1975,8 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR
|
||||||
UINT32 ret, taskID, intSave;
|
UINT32 ret, taskID, intSave;
|
||||||
SchedParam param = { 0 };
|
SchedParam param = { 0 };
|
||||||
|
|
||||||
SCHEDULER_LOCK(intSave);
|
|
||||||
if (OsProcessIsUserMode(childProcessCB)) {
|
|
||||||
taskParam.pfnTaskEntry = runTask->taskEntry;
|
|
||||||
taskParam.uwStackSize = runTask->stackSize;
|
|
||||||
taskParam.userParam.userArea = runTask->userArea;
|
|
||||||
taskParam.userParam.userMapBase = runTask->userMapBase;
|
|
||||||
taskParam.userParam.userMapSize = runTask->userMapSize;
|
|
||||||
} else {
|
|
||||||
taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)entry;
|
|
||||||
taskParam.uwStackSize = size;
|
|
||||||
}
|
|
||||||
if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
|
|
||||||
taskParam.uwResved = LOS_TASK_ATTR_JOINABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
runTask->ops->schedParamGet(runTask, ¶m);
|
|
||||||
SCHEDULER_UNLOCK(intSave);
|
|
||||||
|
|
||||||
taskParam.pcName = (CHAR *)name;
|
taskParam.pcName = (CHAR *)name;
|
||||||
taskParam.policy = param.policy;
|
GetCopyTaskParam(childProcessCB, entry, size, &taskParam, ¶m);
|
||||||
taskParam.usTaskPrio = param.priority;
|
|
||||||
taskParam.processID = (UINTPTR)childProcessCB;
|
|
||||||
|
|
||||||
ret = LOS_TaskCreateOnly(&taskID, &taskParam);
|
ret = LOS_TaskCreateOnly(&taskID, &taskParam);
|
||||||
if (ret != LOS_OK) {
|
if (ret != LOS_OK) {
|
||||||
|
|
|
@ -543,6 +543,7 @@ STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
|
||||||
UINT32 ret;
|
UINT32 ret;
|
||||||
UINT32 numCount;
|
UINT32 numCount;
|
||||||
SchedParam schedParam = { 0 };
|
SchedParam schedParam = { 0 };
|
||||||
|
LosSchedParam initSchedParam = {0};
|
||||||
UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy;
|
UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy;
|
||||||
|
|
||||||
TaskCBBaseInit(taskCB, initParam);
|
TaskCBBaseInit(taskCB, initParam);
|
||||||
|
@ -553,7 +554,14 @@ STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = OsSchedParamInit(taskCB, policy, &schedParam, initParam);
|
if (policy == LOS_SCHED_DEADLINE) {
|
||||||
|
initSchedParam.runTimeUs = initParam->runTimeUs;
|
||||||
|
initSchedParam.deadlineUs = initParam->deadlineUs;
|
||||||
|
initSchedParam.periodUs = initParam->periodUs;
|
||||||
|
} else {
|
||||||
|
initSchedParam.priority = initParam->usTaskPrio;
|
||||||
|
}
|
||||||
|
ret = OsSchedParamInit(taskCB, policy, &schedParam, &initSchedParam);
|
||||||
if (ret != LOS_OK) {
|
if (ret != LOS_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1365,6 +1373,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
|
||||||
UINT32 taskID;
|
UINT32 taskID;
|
||||||
UINT32 ret;
|
UINT32 ret;
|
||||||
UINT32 intSave;
|
UINT32 intSave;
|
||||||
|
INT32 policy;
|
||||||
|
SchedParam param;
|
||||||
|
|
||||||
ret = OsCreateUserTaskParamCheck(processID, initParam);
|
ret = OsCreateUserTaskParamCheck(processID, initParam);
|
||||||
if (ret != LOS_OK) {
|
if (ret != LOS_OK) {
|
||||||
|
@ -1373,14 +1383,25 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
|
||||||
|
|
||||||
initParam->uwStackSize = OS_USER_TASK_SYSCALL_STACK_SIZE;
|
initParam->uwStackSize = OS_USER_TASK_SYSCALL_STACK_SIZE;
|
||||||
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;
|
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;
|
||||||
initParam->policy = LOS_SCHED_RR;
|
|
||||||
if (processID == OS_INVALID_VALUE) {
|
if (processID == OS_INVALID_VALUE) {
|
||||||
SCHEDULER_LOCK(intSave);
|
SCHEDULER_LOCK(intSave);
|
||||||
LosProcessCB *processCB = OsCurrProcessGet();
|
LosProcessCB *processCB = OsCurrProcessGet();
|
||||||
initParam->processID = (UINTPTR)processCB;
|
initParam->processID = (UINTPTR)processCB;
|
||||||
initParam->consoleID = processCB->consoleID;
|
initParam->consoleID = processCB->consoleID;
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
ret = LOS_GetProcessScheduler(processCB->processID, &policy, NULL);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
return OS_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
initParam->policy = policy;
|
||||||
|
if (policy == LOS_SCHED_DEADLINE) {
|
||||||
|
OsSchedProcessDefaultSchedParamGet((UINT16)policy, ¶m);
|
||||||
|
initParam->runTimeUs = param.runTimeUs;
|
||||||
|
initParam->deadlineUs = param.deadlineUs;
|
||||||
|
initParam->periodUs = param.periodUs;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
initParam->policy = LOS_SCHED_RR;
|
||||||
initParam->processID = processID;
|
initParam->processID = processID;
|
||||||
initParam->consoleID = 0;
|
initParam->consoleID = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,7 +535,7 @@ extern LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR sta
|
||||||
extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldAspace, UINTPTR oldFiles);
|
extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldAspace, UINTPTR oldFiles);
|
||||||
extern UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize);
|
extern UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize);
|
||||||
extern UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name);
|
extern UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name);
|
||||||
extern INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy);
|
extern INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 policy, const LosSchedParam *param);
|
||||||
extern INT32 OsGetProcessPriority(INT32 which, INT32 pid);
|
extern INT32 OsGetProcessPriority(INT32 which, INT32 pid);
|
||||||
extern LosProcessCB *OsGetUserInitProcess(VOID);
|
extern LosProcessCB *OsGetUserInitProcess(VOID);
|
||||||
extern LosProcessCB *OsGetIdleProcess(VOID);
|
extern LosProcessCB *OsGetIdleProcess(VOID);
|
||||||
|
@ -553,6 +553,7 @@ extern VOID OsProcessThreadGroupDestroy(VOID);
|
||||||
extern UINT32 OsGetProcessGroupCB(UINT32 pid, UINTPTR *ppgroupLeader);
|
extern UINT32 OsGetProcessGroupCB(UINT32 pid, UINTPTR *ppgroupLeader);
|
||||||
extern LosProcessCB *OsGetDefaultProcessCB(VOID);
|
extern LosProcessCB *OsGetDefaultProcessCB(VOID);
|
||||||
extern ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB);
|
extern ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB);
|
||||||
|
INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,10 @@ extern "C" {
|
||||||
#define OS_SCHED_TICK_TO_CYCLE(ticks) ((UINT64)ticks * OS_CYCLE_PER_TICK)
|
#define OS_SCHED_TICK_TO_CYCLE(ticks) ((UINT64)ticks * OS_CYCLE_PER_TICK)
|
||||||
#define AFFI_MASK_TO_CPUID(mask) ((UINT16)((mask) - 1))
|
#define AFFI_MASK_TO_CPUID(mask) ((UINT16)((mask) - 1))
|
||||||
|
|
||||||
|
#define OS_SCHED_EDF_MIN_RUNTIME 100 /* 100 us */
|
||||||
|
#define OS_SCHED_EDF_MIN_DEADLINE 400 /* 400 us */
|
||||||
|
#define OS_SCHED_EDF_MAX_DEADLINE 5000000 /* 5 s */
|
||||||
|
|
||||||
extern UINT32 g_taskScheduled;
|
extern UINT32 g_taskScheduled;
|
||||||
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
|
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
|
||||||
#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK)
|
#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK)
|
||||||
|
@ -98,9 +102,16 @@ typedef struct {
|
||||||
UINT32 queueBitmap;
|
UINT32 queueBitmap;
|
||||||
} HPFRunqueue;
|
} HPFRunqueue;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LOS_DL_LIST root;
|
||||||
|
LOS_DL_LIST waitList;
|
||||||
|
UINT64 period;
|
||||||
|
} EDFRunqueue;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SortLinkAttribute timeoutQueue; /* task timeout queue */
|
SortLinkAttribute timeoutQueue; /* task timeout queue */
|
||||||
HPFRunqueue *hpfRunqueue;
|
HPFRunqueue *hpfRunqueue;
|
||||||
|
EDFRunqueue *edfRunqueue;
|
||||||
UINT64 responseTime; /* Response time for current CPU tick interrupts */
|
UINT64 responseTime; /* Response time for current CPU tick interrupts */
|
||||||
UINT32 responseID; /* The response ID of the current CPU tick interrupt */
|
UINT32 responseID; /* The response ID of the current CPU tick interrupt */
|
||||||
LosTaskCB *idleTask; /* idle task id */
|
LosTaskCB *idleTask; /* idle task id */
|
||||||
|
@ -216,26 +227,48 @@ STATIC INLINE VOID OsSchedRunqueuePendingSet(VOID)
|
||||||
#define LOS_SCHED_FIFO 1U
|
#define LOS_SCHED_FIFO 1U
|
||||||
#define LOS_SCHED_RR 2U
|
#define LOS_SCHED_RR 2U
|
||||||
#define LOS_SCHED_IDLE 3U
|
#define LOS_SCHED_IDLE 3U
|
||||||
|
#define LOS_SCHED_DEADLINE 6U
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT16 policy;
|
UINT16 policy;
|
||||||
|
/* HPF scheduling parameters */
|
||||||
UINT16 basePrio;
|
UINT16 basePrio;
|
||||||
UINT16 priority;
|
UINT16 priority;
|
||||||
UINT32 timeSlice;
|
UINT32 timeSlice;
|
||||||
|
|
||||||
|
/* EDF scheduling parameters */
|
||||||
|
INT32 runTimeUs;
|
||||||
|
UINT32 deadlineUs;
|
||||||
|
UINT32 periodUs;
|
||||||
} SchedParam;
|
} SchedParam;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT16 policy; /* This field must be present for all scheduling policies and must be the first in the structure */
|
UINT16 policy; /* This field must be present for all scheduling policies and must be the first in the structure */
|
||||||
UINT16 basePrio;
|
UINT16 basePrio;
|
||||||
UINT16 priority;
|
UINT16 priority;
|
||||||
UINT32 initTimeSlice;
|
UINT32 initTimeSlice; /* cycle */
|
||||||
UINT32 priBitmap; /**< Bitmap for recording the change of task priority, the priority can not be greater than 31 */
|
UINT32 priBitmap; /* Bitmap for recording the change of task priority, the priority can not be greater than 31 */
|
||||||
} SchedHPF;
|
} SchedHPF;
|
||||||
|
|
||||||
|
#define EDF_UNUSED 0
|
||||||
|
#define EDF_NEXT_PERIOD 1
|
||||||
|
#define EDF_WAIT_FOREVER 2
|
||||||
|
#define EDF_INIT 3
|
||||||
|
typedef struct {
|
||||||
|
UINT16 policy;
|
||||||
|
UINT16 cpuid;
|
||||||
|
UINT32 flags;
|
||||||
|
INT32 runTime; /* cycle */
|
||||||
|
UINT64 deadline; /* deadline >> runTime */
|
||||||
|
UINT64 period; /* period >= deadline */
|
||||||
|
UINT64 finishTime; /* startTime + deadline */
|
||||||
|
} SchedEDF;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
|
SchedEDF edf;
|
||||||
SchedHPF hpf;
|
SchedHPF hpf;
|
||||||
} Policy;
|
};
|
||||||
} SchedPolicy;
|
} SchedPolicy;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -243,6 +276,7 @@ typedef struct {
|
||||||
VOID (*enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB);
|
VOID (*enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB);
|
||||||
VOID (*start)(SchedRunqueue *rq, LosTaskCB *taskCB);
|
VOID (*start)(SchedRunqueue *rq, LosTaskCB *taskCB);
|
||||||
VOID (*exit)(LosTaskCB *taskCB);
|
VOID (*exit)(LosTaskCB *taskCB);
|
||||||
|
UINT64 (*waitTimeGet)(LosTaskCB *taskCB);
|
||||||
UINT32 (*wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout);
|
UINT32 (*wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout);
|
||||||
VOID (*wake)(LosTaskCB *taskCB);
|
VOID (*wake)(LosTaskCB *taskCB);
|
||||||
BOOL (*schedParamModify)(LosTaskCB *taskCB, const SchedParam *param);
|
BOOL (*schedParamModify)(LosTaskCB *taskCB, const SchedParam *param);
|
||||||
|
@ -463,6 +497,12 @@ STATIC INLINE BOOL OsTaskIsBlocked(const LosTaskCB *taskCB)
|
||||||
return ((taskCB->taskStatus & (OS_TASK_STATUS_SUSPENDED | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) != 0);
|
return ((taskCB->taskStatus & (OS_TASK_STATUS_SUSPENDED | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC INLINE BOOL OsSchedPolicyIsEDF(const LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
const SchedEDF *sched = (const SchedEDF *)&taskCB->sp;
|
||||||
|
return (sched->policy == LOS_SCHED_DEADLINE);
|
||||||
|
}
|
||||||
|
|
||||||
STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID)
|
STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID)
|
||||||
{
|
{
|
||||||
return (LosTaskCB *)ArchCurrTaskGet();
|
return (LosTaskCB *)ArchCurrTaskGet();
|
||||||
|
@ -623,6 +663,16 @@ STATIC INLINE VOID SchedTaskUnfreeze(LosTaskCB *taskCB)
|
||||||
BOOL OsSchedLimitCheckTime(LosTaskCB *task);
|
BOOL OsSchedLimitCheckTime(LosTaskCB *task);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
STATIC INLINE LosTaskCB *EDFRunqueueTopTaskGet(EDFRunqueue *rq)
|
||||||
|
{
|
||||||
|
LOS_DL_LIST *root = &rq->root;
|
||||||
|
if (LOS_ListEmpty(root)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(root), LosTaskCB, pendList);
|
||||||
|
}
|
||||||
|
|
||||||
STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq)
|
STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq)
|
||||||
{
|
{
|
||||||
LosTaskCB *newTask = NULL;
|
LosTaskCB *newTask = NULL;
|
||||||
|
@ -660,9 +710,16 @@ STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID EDFProcessDefaultSchedParamGet(SchedParam *param);
|
||||||
|
VOID EDFSchedPolicyInit(SchedRunqueue *rq);
|
||||||
|
UINT32 EDFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
||||||
|
const SchedParam *parentParam,
|
||||||
|
const LosSchedParam *param);
|
||||||
|
|
||||||
VOID HPFSchedPolicyInit(SchedRunqueue *rq);
|
VOID HPFSchedPolicyInit(SchedRunqueue *rq);
|
||||||
VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
||||||
const SchedParam *parentParam, const TSK_INIT_PARAM_S *param);
|
const SchedParam *parentParam,
|
||||||
|
const LosSchedParam *param);
|
||||||
VOID HPFProcessDefaultSchedParamGet(SchedParam *param);
|
VOID HPFProcessDefaultSchedParamGet(SchedParam *param);
|
||||||
|
|
||||||
VOID IdleTaskSchedParamInit(LosTaskCB *taskCB);
|
VOID IdleTaskSchedParamInit(LosTaskCB *taskCB);
|
||||||
|
@ -670,7 +727,8 @@ VOID IdleTaskSchedParamInit(LosTaskCB *taskCB);
|
||||||
INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2);
|
INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2);
|
||||||
VOID OsSchedPriorityInheritance(LosTaskCB *owner, const SchedParam *param);
|
VOID OsSchedPriorityInheritance(LosTaskCB *owner, const SchedParam *param);
|
||||||
UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
||||||
const SchedParam *parentParam, const TSK_INIT_PARAM_S *param);
|
const SchedParam *parentParam,
|
||||||
|
const LosSchedParam *param);
|
||||||
VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param);
|
VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param);
|
||||||
|
|
||||||
VOID OsSchedResponseTimeReset(UINT64 responseTime);
|
VOID OsSchedResponseTimeReset(UINT64 responseTime);
|
||||||
|
|
|
@ -57,9 +57,11 @@ typedef struct {
|
||||||
#ifdef LOSCFG_SCHED_TICK_DEBUG
|
#ifdef LOSCFG_SCHED_TICK_DEBUG
|
||||||
VOID OsSchedDebugRecordData(VOID);
|
VOID OsSchedDebugRecordData(VOID);
|
||||||
UINT32 OsShellShowTickResponse(VOID);
|
UINT32 OsShellShowTickResponse(VOID);
|
||||||
UINT32 OsShellShowSchedStatistics(VOID);
|
|
||||||
UINT32 OsSchedDebugInit(VOID);
|
UINT32 OsSchedDebugInit(VOID);
|
||||||
#endif
|
#endif
|
||||||
|
UINT32 OsShellShowSchedStatistics(VOID);
|
||||||
|
UINT32 OsShellShowEdfSchedStatistics(VOID);
|
||||||
|
VOID EDFDebugRecord(UINTPTR *taskCB, UINT64 oldFinish);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -101,6 +101,16 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
|
#define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
|
||||||
|
|
||||||
|
#define OS_US_TO_CYCLE(time, freq) ((((time) / OS_SYS_US_PER_SECOND) * (freq)) + \
|
||||||
|
(((time) % OS_SYS_US_PER_SECOND) * (freq) / OS_SYS_US_PER_SECOND))
|
||||||
|
|
||||||
|
#define OS_SYS_US_TO_CYCLE(time) OS_US_TO_CYCLE((time), OS_SYS_CLOCK)
|
||||||
|
|
||||||
|
#define OS_CYCLE_TO_US(cycle, freq) ((((cycle) / (freq)) * OS_SYS_US_PER_SECOND) + \
|
||||||
|
((cycle) % (freq) * OS_SYS_US_PER_SECOND / (freq)))
|
||||||
|
|
||||||
|
#define OS_SYS_CYCLE_TO_US(cycle) OS_CYCLE_TO_US((cycle), OS_SYS_CLOCK)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup los_sys
|
* @ingroup los_sys
|
||||||
* The maximum length of name.
|
* The maximum length of name.
|
||||||
|
|
|
@ -53,6 +53,9 @@
|
||||||
#include "los_sched_pri.h"
|
#include "los_sched_pri.h"
|
||||||
#include "los_swtmr_pri.h"
|
#include "los_swtmr_pri.h"
|
||||||
#include "los_info_pri.h"
|
#include "los_info_pri.h"
|
||||||
|
#ifdef LOSCFG_SCHED_DEBUG
|
||||||
|
#include "los_statistics_pri.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OS_PROCESS_MEM_INFO 0x2U
|
#define OS_PROCESS_MEM_INFO 0x2U
|
||||||
#undef SHOW
|
#undef SHOW
|
||||||
|
@ -93,6 +96,8 @@ STATIC UINT8 *ConvertSchedPolicyToString(UINT16 policy)
|
||||||
return (UINT8 *)"RR";
|
return (UINT8 *)"RR";
|
||||||
} else if (policy == LOS_SCHED_FIFO) {
|
} else if (policy == LOS_SCHED_FIFO) {
|
||||||
return (UINT8 *)"FIFO";
|
return (UINT8 *)"FIFO";
|
||||||
|
} else if (policy == LOS_SCHED_DEADLINE) {
|
||||||
|
return (UINT8 *)"EDF";
|
||||||
} else if (policy == LOS_SCHED_IDLE) {
|
} else if (policy == LOS_SCHED_IDLE) {
|
||||||
return (UINT8 *)"IDLE";
|
return (UINT8 *)"IDLE";
|
||||||
}
|
}
|
||||||
|
@ -200,12 +205,10 @@ STATIC UINT8 *ConvertTaskStatusToString(UINT16 taskStatus)
|
||||||
return (UINT8 *)"Suspended";
|
return (UINT8 *)"Suspended";
|
||||||
} else if (taskStatus & OS_TASK_STATUS_DELAY) {
|
} else if (taskStatus & OS_TASK_STATUS_DELAY) {
|
||||||
return (UINT8 *)"Delay";
|
return (UINT8 *)"Delay";
|
||||||
} else if (taskStatus & OS_TASK_STATUS_PENDING) {
|
} else if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
|
||||||
if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
|
|
||||||
return (UINT8 *)"PendTime";
|
return (UINT8 *)"PendTime";
|
||||||
} else {
|
} else if (taskStatus & OS_TASK_STATUS_PENDING) {
|
||||||
return (UINT8 *)"Pending";
|
return (UINT8 *)"Pending";
|
||||||
}
|
|
||||||
} else if (taskStatus & OS_TASK_STATUS_EXIT) {
|
} else if (taskStatus & OS_TASK_STATUS_EXIT) {
|
||||||
return (UINT8 *)"Exit";
|
return (UINT8 *)"Exit";
|
||||||
}
|
}
|
||||||
|
@ -413,11 +416,20 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv)
|
||||||
}
|
}
|
||||||
goto TASK_HELP;
|
goto TASK_HELP;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
} else if (strcmp("-t", argv[0]) == 0) {
|
} else if (strcmp("-t", argv[0]) == 0) {
|
||||||
if (!OsShellShowSchedStatistics()) {
|
if (!OsShellShowSchedStatistics()) {
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
}
|
}
|
||||||
goto TASK_HELP;
|
goto TASK_HELP;
|
||||||
|
#endif
|
||||||
|
#ifdef LOSCFG_SCHED_EDF_DEBUG
|
||||||
|
} else if (strcmp("-e", argv[0]) == 0) {
|
||||||
|
if (!OsShellShowEdfSchedStatistics()) {
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
goto TASK_HELP;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
goto TASK_HELP;
|
goto TASK_HELP;
|
||||||
|
|
|
@ -0,0 +1,403 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "los_sched_pri.h"
|
||||||
|
#include "los_task_pri.h"
|
||||||
|
#include "los_process_pri.h"
|
||||||
|
#include "los_hook.h"
|
||||||
|
#include "los_tick_pri.h"
|
||||||
|
#include "los_sys_pri.h"
|
||||||
|
|
||||||
|
STATIC EDFRunqueue g_schedEDF;
|
||||||
|
|
||||||
|
STATIC VOID EDFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB);
|
||||||
|
STATIC VOID EDFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB);
|
||||||
|
STATIC UINT64 EDFWaitTimeGet(LosTaskCB *taskCB);
|
||||||
|
STATIC UINT32 EDFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks);
|
||||||
|
STATIC VOID EDFWake(LosTaskCB *resumedTask);
|
||||||
|
STATIC BOOL EDFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param);
|
||||||
|
STATIC UINT32 EDFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param);
|
||||||
|
STATIC UINT32 EDFDelay(LosTaskCB *runTask, UINT64 waitTime);
|
||||||
|
STATIC VOID EDFYield(LosTaskCB *runTask);
|
||||||
|
STATIC VOID EDFExit(LosTaskCB *taskCB);
|
||||||
|
STATIC UINT32 EDFSuspend(LosTaskCB *taskCB);
|
||||||
|
STATIC UINT32 EDFResume(LosTaskCB *taskCB, BOOL *needSched);
|
||||||
|
STATIC UINT64 EDFTimeSliceGet(const LosTaskCB *taskCB);
|
||||||
|
STATIC VOID EDFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime);
|
||||||
|
STATIC INT32 EDFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2);
|
||||||
|
STATIC VOID EDFPriorityInheritance(LosTaskCB *owner, const SchedParam *param);
|
||||||
|
STATIC VOID EDFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param);
|
||||||
|
|
||||||
|
const STATIC SchedOps g_deadlineOps = {
|
||||||
|
.dequeue = EDFDequeue,
|
||||||
|
.enqueue = EDFEnqueue,
|
||||||
|
.waitTimeGet = EDFWaitTimeGet,
|
||||||
|
.wait = EDFWait,
|
||||||
|
.wake = EDFWake,
|
||||||
|
.schedParamModify = EDFSchedParamModify,
|
||||||
|
.schedParamGet = EDFSchedParamGet,
|
||||||
|
.delay = EDFDelay,
|
||||||
|
.yield = EDFYield,
|
||||||
|
.start = EDFDequeue,
|
||||||
|
.exit = EDFExit,
|
||||||
|
.suspend = EDFSuspend,
|
||||||
|
.resume = EDFResume,
|
||||||
|
.deadlineGet = EDFTimeSliceGet,
|
||||||
|
.timeSliceUpdate = EDFTimeSliceUpdate,
|
||||||
|
.schedParamCompare = EDFParamCompare,
|
||||||
|
.priorityInheritance = EDFPriorityInheritance,
|
||||||
|
.priorityRestore = EDFPriorityRestore,
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC VOID EDFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime)
|
||||||
|
{
|
||||||
|
SchedEDF *sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
|
||||||
|
LOS_ASSERT(currTime >= taskCB->startTime);
|
||||||
|
|
||||||
|
if (taskCB->timeSlice <= 0) {
|
||||||
|
taskCB->irqUsedTime = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 incTime = (currTime - taskCB->startTime - taskCB->irqUsedTime);
|
||||||
|
LOS_ASSERT(incTime >= 0);
|
||||||
|
|
||||||
|
#ifdef LOSCFG_SCHED_EDF_DEBUG
|
||||||
|
taskCB->schedStat.timeSliceRealTime += incTime;
|
||||||
|
taskCB->schedStat.allRuntime += (currTime - taskCB->startTime);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
taskCB->timeSlice -= incTime;
|
||||||
|
taskCB->irqUsedTime = 0;
|
||||||
|
taskCB->startTime = currTime;
|
||||||
|
|
||||||
|
if ((sched->finishTime > currTime) && (taskCB->timeSlice > 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rq->schedFlag |= INT_PEND_RESCH;
|
||||||
|
if (sched->finishTime <= currTime) {
|
||||||
|
#ifdef LOSCFG_SCHED_EDF_DEBUG
|
||||||
|
EDFDebugRecord((UINTPTR *)taskCB, sched->finishTime);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
taskCB->timeSlice = 0;
|
||||||
|
PrintExcInfo("EDF task %u is timeout, runTime: %d us period: %llu us\n", taskCB->taskID,
|
||||||
|
(INT32)OS_SYS_CYCLE_TO_US((UINT64)sched->runTime), OS_SYS_CYCLE_TO_US(sched->period));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT64 EDFTimeSliceGet(const LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
SchedEDF *sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
UINT64 endTime = taskCB->startTime + taskCB->timeSlice;
|
||||||
|
return (endTime > sched->finishTime) ? sched->finishTime : endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID DeadlineQueueInsert(EDFRunqueue *rq, LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
LOS_DL_LIST *root = &rq->root;
|
||||||
|
if (LOS_ListEmpty(root)) {
|
||||||
|
LOS_ListTailInsert(root, &taskCB->pendList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOS_DL_LIST *list = root->pstNext;
|
||||||
|
do {
|
||||||
|
LosTaskCB *readyTask = LOS_DL_LIST_ENTRY(list, LosTaskCB, pendList);
|
||||||
|
if (EDFParamCompare(&readyTask->sp, &taskCB->sp) > 0) {
|
||||||
|
LOS_ListHeadInsert(list, &taskCB->pendList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
list = list->pstNext;
|
||||||
|
} while (list != root);
|
||||||
|
|
||||||
|
LOS_ListHeadInsert(list, &taskCB->pendList);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID EDFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY));
|
||||||
|
|
||||||
|
EDFRunqueue *erq = rq->edfRunqueue;
|
||||||
|
SchedEDF *sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
if (taskCB->timeSlice <= 0) {
|
||||||
|
#ifdef LOSCFG_SCHED_EDF_DEBUG
|
||||||
|
UINT64 oldFinish = sched->finishTime;
|
||||||
|
#endif
|
||||||
|
UINT64 currTime = OsGetCurrSchedTimeCycle();
|
||||||
|
if (sched->flags == EDF_INIT) {
|
||||||
|
sched->finishTime = currTime;
|
||||||
|
} else if (sched->flags != EDF_NEXT_PERIOD) {
|
||||||
|
/* The start time of the next period */
|
||||||
|
sched->finishTime = (sched->finishTime - sched->deadline) + sched->period;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the start time of the next period */
|
||||||
|
while (1) {
|
||||||
|
/* The deadline of the next period */
|
||||||
|
UINT64 finishTime = sched->finishTime + sched->deadline;
|
||||||
|
if ((finishTime <= currTime) || ((sched->finishTime + sched->runTime) > finishTime)) {
|
||||||
|
/* This period cannot meet the minimum running time, so it is migrated to the next period */
|
||||||
|
sched->finishTime += sched->period;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sched->finishTime > currTime) {
|
||||||
|
/* Wait for the next period to start */
|
||||||
|
LOS_ListTailInsert(&erq->waitList, &taskCB->pendList);
|
||||||
|
taskCB->waitTime = OS_SCHED_MAX_RESPONSE_TIME;
|
||||||
|
if (!OsTaskIsRunning(taskCB)) {
|
||||||
|
OsSchedTimeoutQueueAdd(taskCB, sched->finishTime);
|
||||||
|
}
|
||||||
|
#ifdef LOSCFG_SCHED_EDF_DEBUG
|
||||||
|
if (oldFinish != sched->finishTime) {
|
||||||
|
EDFDebugRecord((UINTPTR *)taskCB, oldFinish);
|
||||||
|
taskCB->schedStat.allRuntime = 0;
|
||||||
|
taskCB->schedStat.timeSliceRealTime = 0;
|
||||||
|
taskCB->schedStat.pendTime = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
taskCB->taskStatus |= OS_TASK_STATUS_PEND_TIME;
|
||||||
|
sched->flags = EDF_NEXT_PERIOD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sched->finishTime += sched->deadline;
|
||||||
|
taskCB->timeSlice = sched->runTime;
|
||||||
|
sched->flags = EDF_UNUSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeadlineQueueInsert(erq, taskCB);
|
||||||
|
taskCB->taskStatus &= ~(OS_TASK_STATUS_BLOCKED | OS_TASK_STATUS_TIMEOUT);
|
||||||
|
taskCB->taskStatus |= OS_TASK_STATUS_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID EDFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
(VOID)rq;
|
||||||
|
LOS_ListDelete(&taskCB->pendList);
|
||||||
|
taskCB->taskStatus &= ~OS_TASK_STATUS_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID EDFExit(LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
|
||||||
|
EDFDequeue(OsSchedRunqueue(), taskCB);
|
||||||
|
} else if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) {
|
||||||
|
LOS_ListDelete(&taskCB->pendList);
|
||||||
|
taskCB->taskStatus &= ~OS_TASK_STATUS_PENDING;
|
||||||
|
}
|
||||||
|
if (taskCB->taskStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) {
|
||||||
|
OsSchedTimeoutQueueDelete(taskCB);
|
||||||
|
taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID EDFYield(LosTaskCB *runTask)
|
||||||
|
{
|
||||||
|
SchedRunqueue *rq = OsSchedRunqueue();
|
||||||
|
runTask->timeSlice = 0;
|
||||||
|
|
||||||
|
runTask->startTime = OsGetCurrSchedTimeCycle();
|
||||||
|
EDFEnqueue(rq, runTask);
|
||||||
|
OsSchedResched();
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 EDFDelay(LosTaskCB *runTask, UINT64 waitTime)
|
||||||
|
{
|
||||||
|
runTask->taskStatus |= OS_TASK_STATUS_DELAY;
|
||||||
|
runTask->waitTime = waitTime;
|
||||||
|
OsSchedResched();
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT64 EDFWaitTimeGet(LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
const SchedEDF *sched = (const SchedEDF *)&taskCB->sp;
|
||||||
|
if (sched->flags != EDF_WAIT_FOREVER) {
|
||||||
|
taskCB->waitTime += taskCB->startTime;
|
||||||
|
}
|
||||||
|
return (taskCB->waitTime >= sched->finishTime) ? sched->finishTime : taskCB->waitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 EDFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks)
|
||||||
|
{
|
||||||
|
SchedEDF *sched = (SchedEDF *)&runTask->sp;
|
||||||
|
runTask->taskStatus |= (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME);
|
||||||
|
LOS_ListTailInsert(list, &runTask->pendList);
|
||||||
|
|
||||||
|
if (ticks != LOS_WAIT_FOREVER) {
|
||||||
|
runTask->waitTime = OS_SCHED_TICK_TO_CYCLE(ticks);
|
||||||
|
} else {
|
||||||
|
sched->flags = EDF_WAIT_FOREVER;
|
||||||
|
runTask->waitTime = OS_SCHED_MAX_RESPONSE_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OsPreemptableInSched()) {
|
||||||
|
OsSchedResched();
|
||||||
|
if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {
|
||||||
|
runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;
|
||||||
|
return LOS_ERRNO_TSK_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID EDFWake(LosTaskCB *resumedTask)
|
||||||
|
{
|
||||||
|
LOS_ListDelete(&resumedTask->pendList);
|
||||||
|
resumedTask->taskStatus &= ~OS_TASK_STATUS_PENDING;
|
||||||
|
|
||||||
|
if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) {
|
||||||
|
OsSchedTimeoutQueueDelete(resumedTask);
|
||||||
|
resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) {
|
||||||
|
#ifdef LOSCFG_SCHED_EDF_DEBUG
|
||||||
|
resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime;
|
||||||
|
resumedTask->schedStat.pendCount++;
|
||||||
|
#endif
|
||||||
|
EDFEnqueue(OsSchedRunqueue(), resumedTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC BOOL EDFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param)
|
||||||
|
{
|
||||||
|
SchedRunqueue *rq = OsSchedRunqueue();
|
||||||
|
SchedEDF *sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
|
||||||
|
taskCB->timeSlice = 0;
|
||||||
|
sched->runTime = (INT32)OS_SYS_US_TO_CYCLE(param->runTimeUs);
|
||||||
|
sched->period = OS_SYS_US_TO_CYCLE(param->periodUs);
|
||||||
|
|
||||||
|
if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
|
||||||
|
EDFDequeue(rq, taskCB);
|
||||||
|
sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs);
|
||||||
|
EDFEnqueue(rq, taskCB);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs);
|
||||||
|
if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {
|
||||||
|
EDFEnqueue(rq, taskCB);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 EDFSchedParamGet(const LosTaskCB *taskCB, SchedParam *param)
|
||||||
|
{
|
||||||
|
SchedEDF *sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
param->policy = sched->policy;
|
||||||
|
param->runTimeUs = (INT32)OS_SYS_CYCLE_TO_US((UINT64)sched->runTime);
|
||||||
|
param->deadlineUs = OS_SYS_CYCLE_TO_US(sched->deadline);
|
||||||
|
param->periodUs = OS_SYS_CYCLE_TO_US(sched->period);
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 EDFSuspend(LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
return LOS_EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 EDFResume(LosTaskCB *taskCB, BOOL *needSched)
|
||||||
|
{
|
||||||
|
return LOS_EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC INT32 EDFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2)
|
||||||
|
{
|
||||||
|
const SchedEDF *param1 = (const SchedEDF *)sp1;
|
||||||
|
const SchedEDF *param2 = (const SchedEDF *)sp2;
|
||||||
|
|
||||||
|
return (INT32)(param1->finishTime - param2->finishTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID EDFPriorityInheritance(LosTaskCB *owner, const SchedParam *param)
|
||||||
|
{
|
||||||
|
(VOID)owner;
|
||||||
|
(VOID)param;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID EDFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param)
|
||||||
|
{
|
||||||
|
(VOID)owner;
|
||||||
|
(VOID)list;
|
||||||
|
(VOID)param;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 EDFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
||||||
|
const SchedParam *parentParam,
|
||||||
|
const LosSchedParam *param)
|
||||||
|
{
|
||||||
|
(VOID)parentParam;
|
||||||
|
SchedEDF *sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
sched->flags = EDF_INIT;
|
||||||
|
sched->policy = policy;
|
||||||
|
sched->runTime = (INT32)OS_SYS_US_TO_CYCLE((UINT64)param->runTimeUs);
|
||||||
|
sched->deadline = OS_SYS_US_TO_CYCLE(param->deadlineUs);
|
||||||
|
sched->period = OS_SYS_US_TO_CYCLE(param->periodUs);
|
||||||
|
sched->finishTime = 0;
|
||||||
|
taskCB->timeSlice = 0;
|
||||||
|
taskCB->ops = &g_deadlineOps;
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID EDFProcessDefaultSchedParamGet(SchedParam *param)
|
||||||
|
{
|
||||||
|
param->runTimeUs = OS_SCHED_EDF_MIN_RUNTIME;
|
||||||
|
param->deadlineUs = OS_SCHED_EDF_MAX_DEADLINE;
|
||||||
|
param->periodUs = param->deadlineUs;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID EDFSchedPolicyInit(SchedRunqueue *rq)
|
||||||
|
{
|
||||||
|
if (ArchCurrCpuid() > 0) {
|
||||||
|
rq->edfRunqueue = &g_schedEDF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EDFRunqueue *erq = &g_schedEDF;
|
||||||
|
erq->period = OS_SCHED_MAX_RESPONSE_TIME;
|
||||||
|
LOS_ListInit(&erq->root);
|
||||||
|
LOS_ListInit(&erq->waitList);
|
||||||
|
rq->edfRunqueue = erq;
|
||||||
|
}
|
|
@ -48,6 +48,7 @@ STATIC VOID IdlePriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const
|
||||||
const STATIC SchedOps g_idleOps = {
|
const STATIC SchedOps g_idleOps = {
|
||||||
.dequeue = IdleDequeue,
|
.dequeue = IdleDequeue,
|
||||||
.enqueue = IdleEnqueue,
|
.enqueue = IdleEnqueue,
|
||||||
|
.waitTimeGet = NULL,
|
||||||
.wait = IdleWait,
|
.wait = IdleWait,
|
||||||
.wake = IdleWake,
|
.wake = IdleWake,
|
||||||
.schedParamModify = NULL,
|
.schedParamModify = NULL,
|
||||||
|
|
|
@ -47,6 +47,7 @@ STATIC HPFRunqueue g_schedHPF;
|
||||||
|
|
||||||
STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB);
|
STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB);
|
||||||
STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB);
|
STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB);
|
||||||
|
STATIC UINT64 HPFWaitTimeGet(LosTaskCB *taskCB);
|
||||||
STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks);
|
STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks);
|
||||||
STATIC VOID HPFWake(LosTaskCB *resumedTask);
|
STATIC VOID HPFWake(LosTaskCB *resumedTask);
|
||||||
STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param);
|
STATIC BOOL HPFSchedParamModify(LosTaskCB *taskCB, const SchedParam *param);
|
||||||
|
@ -66,6 +67,7 @@ STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const
|
||||||
const STATIC SchedOps g_priorityOps = {
|
const STATIC SchedOps g_priorityOps = {
|
||||||
.dequeue = HPFDequeue,
|
.dequeue = HPFDequeue,
|
||||||
.enqueue = HPFEnqueue,
|
.enqueue = HPFEnqueue,
|
||||||
|
.waitTimeGet = HPFWaitTimeGet,
|
||||||
.wait = HPFWait,
|
.wait = HPFWait,
|
||||||
.wake = HPFWake,
|
.wake = HPFWake,
|
||||||
.schedParamModify = HPFSchedParamModify,
|
.schedParamModify = HPFSchedParamModify,
|
||||||
|
@ -94,7 +96,7 @@ STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 curr
|
||||||
|
|
||||||
if (sched->policy == LOS_SCHED_RR) {
|
if (sched->policy == LOS_SCHED_RR) {
|
||||||
taskCB->timeSlice -= incTime;
|
taskCB->timeSlice -= incTime;
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
taskCB->schedStat.timeSliceRealTime += incTime;
|
taskCB->schedStat.timeSliceRealTime += incTime;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -107,7 +109,7 @@ STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 curr
|
||||||
rq->schedFlag |= INT_PEND_RESCH;
|
rq->schedFlag |= INT_PEND_RESCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
taskCB->schedStat.allRuntime += incTime;
|
taskCB->schedStat.allRuntime += incTime;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -215,7 +217,7 @@ STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB)
|
||||||
sched->initTimeSlice = TimeSliceCalculate(rq, sched->basePrio, sched->priority);
|
sched->initTimeSlice = TimeSliceCalculate(rq, sched->basePrio, sched->priority);
|
||||||
taskCB->timeSlice = sched->initTimeSlice;
|
taskCB->timeSlice = sched->initTimeSlice;
|
||||||
PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
|
PriQueTailInsert(rq, sched->basePrio, &taskCB->pendList, sched->priority);
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime;
|
taskCB->schedStat.timeSliceTime = taskCB->schedStat.timeSliceRealTime;
|
||||||
taskCB->schedStat.timeSliceCount++;
|
taskCB->schedStat.timeSliceCount++;
|
||||||
#endif
|
#endif
|
||||||
|
@ -244,7 +246,7 @@ STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB)
|
||||||
|
|
||||||
STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB)
|
STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB)
|
||||||
{
|
{
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
|
if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
|
||||||
taskCB->startTime = OsGetCurrSchedTimeCycle();
|
taskCB->startTime = OsGetCurrSchedTimeCycle();
|
||||||
}
|
}
|
||||||
|
@ -301,6 +303,12 @@ STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime)
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC UINT64 HPFWaitTimeGet(LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
taskCB->waitTime += taskCB->startTime;
|
||||||
|
return taskCB->waitTime;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks)
|
STATIC UINT32 HPFWait(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 ticks)
|
||||||
{
|
{
|
||||||
runTask->taskStatus |= OS_TASK_STATUS_PENDING;
|
runTask->taskStatus |= OS_TASK_STATUS_PENDING;
|
||||||
|
@ -333,7 +341,7 @@ STATIC VOID HPFWake(LosTaskCB *resumedTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) {
|
if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) {
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime;
|
resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime;
|
||||||
resumedTask->schedStat.pendCount++;
|
resumedTask->schedStat.pendCount++;
|
||||||
#endif
|
#endif
|
||||||
|
@ -508,13 +516,13 @@ STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const
|
||||||
|
|
||||||
VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
||||||
const SchedParam *parentParam,
|
const SchedParam *parentParam,
|
||||||
const TSK_INIT_PARAM_S *param)
|
const LosSchedParam *param)
|
||||||
{
|
{
|
||||||
SchedHPF *sched = (SchedHPF *)&taskCB->sp;
|
SchedHPF *sched = (SchedHPF *)&taskCB->sp;
|
||||||
|
|
||||||
sched->policy = policy;
|
sched->policy = policy;
|
||||||
if (param != NULL) {
|
if (param != NULL) {
|
||||||
sched->priority = param->usTaskPrio;
|
sched->priority = param->priority;
|
||||||
} else {
|
} else {
|
||||||
sched->priority = parentParam->priority;
|
sched->priority = parentParam->priority;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,15 +102,26 @@ VOID OsSchedExpireTimeUpdate(VOID)
|
||||||
|
|
||||||
STATIC INLINE VOID SchedTimeoutTaskWake(SchedRunqueue *rq, UINT64 currTime, LosTaskCB *taskCB, BOOL *needSched)
|
STATIC INLINE VOID SchedTimeoutTaskWake(SchedRunqueue *rq, UINT64 currTime, LosTaskCB *taskCB, BOOL *needSched)
|
||||||
{
|
{
|
||||||
#ifndef LOSCFG_SCHED_DEBUG
|
|
||||||
(VOID)currTime;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LOS_SpinLock(&g_taskSpin);
|
LOS_SpinLock(&g_taskSpin);
|
||||||
|
if (OsSchedPolicyIsEDF(taskCB)) {
|
||||||
|
SchedEDF *sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
if (sched->finishTime <= currTime) {
|
||||||
|
if (taskCB->timeSlice >= 0) {
|
||||||
|
PrintExcInfo("EDF task: %u name: %s is timeout, timeout for %llu us.\n",
|
||||||
|
taskCB->taskID, taskCB->taskName, OS_SYS_CYCLE_TO_US(currTime - sched->finishTime));
|
||||||
|
}
|
||||||
|
taskCB->timeSlice = 0;
|
||||||
|
}
|
||||||
|
if (sched->flags == EDF_WAIT_FOREVER) {
|
||||||
|
taskCB->taskStatus &= ~OS_TASK_STATUS_PEND_TIME;
|
||||||
|
sched->flags = EDF_UNUSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UINT16 tempStatus = taskCB->taskStatus;
|
UINT16 tempStatus = taskCB->taskStatus;
|
||||||
if (tempStatus & (OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) {
|
if (tempStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) {
|
||||||
taskCB->taskStatus &= ~(OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY);
|
taskCB->taskStatus &= ~(OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY);
|
||||||
if (tempStatus & OS_TASK_STATUS_PENDING) {
|
if (tempStatus & OS_TASK_STATUS_PEND_TIME) {
|
||||||
taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT;
|
taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT;
|
||||||
LOS_ListDelete(&taskCB->pendList);
|
LOS_ListDelete(&taskCB->pendList);
|
||||||
taskCB->taskMux = NULL;
|
taskCB->taskMux = NULL;
|
||||||
|
@ -118,7 +129,7 @@ STATIC INLINE VOID SchedTimeoutTaskWake(SchedRunqueue *rq, UINT64 currTime, LosT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) {
|
if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) {
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
taskCB->schedStat.pendTime += currTime - taskCB->startTime;
|
taskCB->schedStat.pendTime += currTime - taskCB->startTime;
|
||||||
taskCB->schedStat.pendCount++;
|
taskCB->schedStat.pendCount++;
|
||||||
#endif
|
#endif
|
||||||
|
@ -212,8 +223,10 @@ VOID OsSchedRunqueueIdleInit(LosTaskCB *idleTask)
|
||||||
|
|
||||||
UINT32 OsSchedInit(VOID)
|
UINT32 OsSchedInit(VOID)
|
||||||
{
|
{
|
||||||
for (UINT16 cpuId = 0; cpuId < LOSCFG_KERNEL_CORE_NUM; cpuId++) {
|
for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
|
||||||
HPFSchedPolicyInit(OsSchedRunqueueByID(cpuId));
|
SchedRunqueue *rq = OsSchedRunqueueByID(cpuid);
|
||||||
|
EDFSchedPolicyInit(rq);
|
||||||
|
HPFSchedPolicyInit(rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOSCFG_SCHED_TICK_DEBUG
|
#ifdef LOSCFG_SCHED_TICK_DEBUG
|
||||||
|
@ -247,13 +260,15 @@ INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy, const SchedParam *parentParam, const TSK_INIT_PARAM_S *param)
|
UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy, const SchedParam *parentParam, const LosSchedParam *param)
|
||||||
{
|
{
|
||||||
switch (policy) {
|
switch (policy) {
|
||||||
case LOS_SCHED_FIFO:
|
case LOS_SCHED_FIFO:
|
||||||
case LOS_SCHED_RR:
|
case LOS_SCHED_RR:
|
||||||
HPFTaskSchedParamInit(taskCB, policy, parentParam, param);
|
HPFTaskSchedParamInit(taskCB, policy, parentParam, param);
|
||||||
break;
|
break;
|
||||||
|
case LOS_SCHED_DEADLINE:
|
||||||
|
return EDFTaskSchedParamInit(taskCB, policy, parentParam, param);
|
||||||
case LOS_SCHED_IDLE:
|
case LOS_SCHED_IDLE:
|
||||||
IdleTaskSchedParamInit(taskCB);
|
IdleTaskSchedParamInit(taskCB);
|
||||||
break;
|
break;
|
||||||
|
@ -271,6 +286,9 @@ VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param)
|
||||||
case LOS_SCHED_RR:
|
case LOS_SCHED_RR:
|
||||||
HPFProcessDefaultSchedParamGet(param);
|
HPFProcessDefaultSchedParamGet(param);
|
||||||
break;
|
break;
|
||||||
|
case LOS_SCHED_DEADLINE:
|
||||||
|
EDFProcessDefaultSchedParamGet(param);
|
||||||
|
break;
|
||||||
case LOS_SCHED_IDLE:
|
case LOS_SCHED_IDLE:
|
||||||
default:
|
default:
|
||||||
PRINT_ERR("Invalid process-level scheduling policy, %u\n", policy);
|
PRINT_ERR("Invalid process-level scheduling policy, %u\n", policy);
|
||||||
|
@ -281,12 +299,19 @@ VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param)
|
||||||
|
|
||||||
STATIC LosTaskCB *TopTaskGet(SchedRunqueue *rq)
|
STATIC LosTaskCB *TopTaskGet(SchedRunqueue *rq)
|
||||||
{
|
{
|
||||||
LosTaskCB *newTask = HPFRunqueueTopTaskGet(rq->hpfRunqueue);
|
LosTaskCB *newTask = EDFRunqueueTopTaskGet(rq->edfRunqueue);
|
||||||
|
if (newTask != NULL) {
|
||||||
if (newTask == NULL) {
|
goto FIND;
|
||||||
newTask = rq->idleTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newTask = HPFRunqueueTopTaskGet(rq->hpfRunqueue);
|
||||||
|
if (newTask != NULL) {
|
||||||
|
goto FIND;
|
||||||
|
}
|
||||||
|
|
||||||
|
newTask = rq->idleTask;
|
||||||
|
|
||||||
|
FIND:
|
||||||
newTask->ops->start(rq, newTask);
|
newTask->ops->start(rq, newTask);
|
||||||
return newTask;
|
return newTask;
|
||||||
}
|
}
|
||||||
|
@ -387,7 +412,7 @@ STATIC VOID SchedTaskSwitch(SchedRunqueue *rq, LosTaskCB *runTask, LosTaskCB *ne
|
||||||
OsCpupCycleEndStart(runTask, newTask);
|
OsCpupCycleEndStart(runTask, newTask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
UINT64 waitStartTime = newTask->startTime;
|
UINT64 waitStartTime = newTask->startTime;
|
||||||
#endif
|
#endif
|
||||||
if (runTask->taskStatus & OS_TASK_STATUS_READY) {
|
if (runTask->taskStatus & OS_TASK_STATUS_READY) {
|
||||||
|
@ -400,14 +425,14 @@ STATIC VOID SchedTaskSwitch(SchedRunqueue *rq, LosTaskCB *runTask, LosTaskCB *ne
|
||||||
runTask->ops->timeSliceUpdate(rq, runTask, newTask->startTime);
|
runTask->ops->timeSliceUpdate(rq, runTask, newTask->startTime);
|
||||||
|
|
||||||
if (runTask->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) {
|
if (runTask->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) {
|
||||||
OsSchedTimeoutQueueAdd(runTask, runTask->startTime + runTask->waitTime);
|
OsSchedTimeoutQueueAdd(runTask, runTask->ops->waitTimeGet(runTask));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT64 deadline = newTask->ops->deadlineGet(newTask);
|
UINT64 deadline = newTask->ops->deadlineGet(newTask);
|
||||||
SchedNextExpireTimeSet(newTask->taskID, deadline, runTask->taskID);
|
SchedNextExpireTimeSet(newTask->taskID, deadline, runTask->taskID);
|
||||||
|
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
newTask->schedStat.waitSchedTime += newTask->startTime - waitStartTime;
|
newTask->schedStat.waitSchedTime += newTask->startTime - waitStartTime;
|
||||||
newTask->schedStat.waitSchedCount++;
|
newTask->schedStat.waitSchedCount++;
|
||||||
runTask->schedStat.runTime = runTask->schedStat.allRuntime;
|
runTask->schedStat.runTime = runTask->schedStat.allRuntime;
|
||||||
|
|
|
@ -99,6 +99,7 @@ UINT32 OsShellShowTickResponse(VOID)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||||
STATIC VOID SchedDataGet(const LosTaskCB *taskCB, UINT64 *runTime, UINT64 *timeSlice,
|
STATIC VOID SchedDataGet(const LosTaskCB *taskCB, UINT64 *runTime, UINT64 *timeSlice,
|
||||||
UINT64 *pendTime, UINT64 *schedWait)
|
UINT64 *pendTime, UINT64 *schedWait)
|
||||||
{
|
{
|
||||||
|
@ -128,6 +129,7 @@ UINT32 OsShellShowSchedStatistics(VOID)
|
||||||
UINT32 taskLinkNum[LOSCFG_KERNEL_CORE_NUM];
|
UINT32 taskLinkNum[LOSCFG_KERNEL_CORE_NUM];
|
||||||
UINT32 intSave;
|
UINT32 intSave;
|
||||||
LosTaskCB task;
|
LosTaskCB task;
|
||||||
|
SchedEDF *sched = NULL;
|
||||||
|
|
||||||
SCHEDULER_LOCK(intSave);
|
SCHEDULER_LOCK(intSave);
|
||||||
for (UINT16 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) {
|
for (UINT16 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) {
|
||||||
|
@ -150,6 +152,12 @@ UINT32 OsShellShowSchedStatistics(VOID)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
if (sched->policy == LOS_SCHED_DEADLINE) {
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
(VOID)memcpy_s(&task, sizeof(LosTaskCB), taskCB, sizeof(LosTaskCB));
|
(VOID)memcpy_s(&task, sizeof(LosTaskCB), taskCB, sizeof(LosTaskCB));
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
||||||
|
@ -170,3 +178,168 @@ UINT32 OsShellShowSchedStatistics(VOID)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOSCFG_SCHED_EDF_DEBUG
|
||||||
|
#define EDF_DEBUG_NODE 20
|
||||||
|
typedef struct {
|
||||||
|
UINT32 tid;
|
||||||
|
INT32 runTimeUs;
|
||||||
|
UINT64 deadlineUs;
|
||||||
|
UINT64 periodUs;
|
||||||
|
UINT64 startTime;
|
||||||
|
UINT64 finishTime;
|
||||||
|
UINT64 nextfinishTime;
|
||||||
|
UINT64 timeSliceUnused;
|
||||||
|
UINT64 timeSliceRealTime;
|
||||||
|
UINT64 allRuntime;
|
||||||
|
UINT64 pendTime;
|
||||||
|
} EDFDebug;
|
||||||
|
|
||||||
|
STATIC EDFDebug g_edfNode[EDF_DEBUG_NODE];
|
||||||
|
STATIC INT32 g_edfNodePointer = 0;
|
||||||
|
|
||||||
|
VOID EDFDebugRecord(UINTPTR *task, UINT64 oldFinish)
|
||||||
|
{
|
||||||
|
LosTaskCB *taskCB = (LosTaskCB *)task;
|
||||||
|
SchedEDF *sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
SchedParam param;
|
||||||
|
|
||||||
|
// when print edf info, will stop record
|
||||||
|
if (g_edfNodePointer == (EDF_DEBUG_NODE + 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||||
|
g_edfNode[g_edfNodePointer].tid = taskCB->taskID;
|
||||||
|
g_edfNode[g_edfNodePointer].runTimeUs =param.runTimeUs;
|
||||||
|
g_edfNode[g_edfNodePointer].deadlineUs =param.deadlineUs;
|
||||||
|
g_edfNode[g_edfNodePointer].periodUs =param.periodUs;
|
||||||
|
g_edfNode[g_edfNodePointer].startTime = taskCB->startTime;
|
||||||
|
if (taskCB->timeSlice <= 0) {
|
||||||
|
taskCB->irqUsedTime = 0;
|
||||||
|
g_edfNode[g_edfNodePointer].timeSliceUnused = 0;
|
||||||
|
} else {
|
||||||
|
g_edfNode[g_edfNodePointer].timeSliceUnused = taskCB->timeSlice;
|
||||||
|
}
|
||||||
|
g_edfNode[g_edfNodePointer].finishTime = oldFinish;
|
||||||
|
g_edfNode[g_edfNodePointer].nextfinishTime = sched->finishTime;
|
||||||
|
g_edfNode[g_edfNodePointer].timeSliceRealTime = taskCB->schedStat.timeSliceRealTime;
|
||||||
|
g_edfNode[g_edfNodePointer].allRuntime = taskCB->schedStat.allRuntime;
|
||||||
|
g_edfNode[g_edfNodePointer].pendTime = taskCB->schedStat.pendTime;
|
||||||
|
|
||||||
|
g_edfNodePointer++;
|
||||||
|
if (g_edfNodePointer == EDF_DEBUG_NODE) {
|
||||||
|
g_edfNodePointer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID EDFInfoPrint(int idx)
|
||||||
|
{
|
||||||
|
INT32 runTimeUs;
|
||||||
|
UINT64 deadlineUs;
|
||||||
|
UINT64 periodUs;
|
||||||
|
UINT64 startTime;
|
||||||
|
UINT64 timeSlice;
|
||||||
|
UINT64 finishTime;
|
||||||
|
UINT64 nextfinishTime;
|
||||||
|
UINT64 pendTime;
|
||||||
|
UINT64 allRuntime;
|
||||||
|
UINT64 timeSliceRealTime;
|
||||||
|
CHAR *status = NULL;
|
||||||
|
|
||||||
|
startTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].startTime);
|
||||||
|
timeSlice = OS_SYS_CYCLE_TO_US(g_edfNode[idx].timeSliceUnused);
|
||||||
|
finishTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].finishTime);
|
||||||
|
nextfinishTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].nextfinishTime);
|
||||||
|
pendTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].pendTime);
|
||||||
|
allRuntime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].allRuntime);
|
||||||
|
timeSliceRealTime = OS_SYS_CYCLE_TO_US(g_edfNode[idx].timeSliceRealTime);
|
||||||
|
runTimeUs = g_edfNode[idx].runTimeUs;
|
||||||
|
deadlineUs = g_edfNode[idx].deadlineUs;
|
||||||
|
periodUs = g_edfNode[idx].periodUs;
|
||||||
|
|
||||||
|
if (timeSlice > 0) {
|
||||||
|
status = "TIMEOUT";
|
||||||
|
} else if (nextfinishTime == finishTime) {
|
||||||
|
status = "NEXT PERIOD";
|
||||||
|
} else {
|
||||||
|
status = "WAIT RUN";
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINTK("%4u%9d%9llu%9llu%12llu%12llu%12llu%9llu%9llu%9llu%9llu %-12s\n",
|
||||||
|
g_edfNode[idx].tid, runTimeUs, deadlineUs, periodUs,
|
||||||
|
startTime, finishTime, nextfinishTime, allRuntime, timeSliceRealTime,
|
||||||
|
timeSlice, pendTime, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID OsEDFDebugPrint(VOID)
|
||||||
|
{
|
||||||
|
INT32 max;
|
||||||
|
UINT32 intSave;
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
SCHEDULER_LOCK(intSave);
|
||||||
|
max = g_edfNodePointer;
|
||||||
|
g_edfNodePointer = EDF_DEBUG_NODE + 1;
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
||||||
|
PRINTK("\r\nlast %d sched is: (in microsecond)\r\n", EDF_DEBUG_NODE);
|
||||||
|
|
||||||
|
PRINTK(" TID RunTime Deadline Period StartTime "
|
||||||
|
"CurPeriod NextPeriod AllRun RealRun TimeOut WaitTime Status\n");
|
||||||
|
|
||||||
|
for (i = max; i < EDF_DEBUG_NODE; i++) {
|
||||||
|
EDFInfoPrint(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < max; i++) {
|
||||||
|
EDFInfoPrint(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
SCHEDULER_LOCK(intSave);
|
||||||
|
g_edfNodePointer = max;
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 OsShellShowEdfSchedStatistics(VOID)
|
||||||
|
{
|
||||||
|
UINT32 intSave;
|
||||||
|
LosTaskCB task;
|
||||||
|
UINT64 curTime;
|
||||||
|
UINT64 deadline;
|
||||||
|
UINT64 finishTime;
|
||||||
|
SchedEDF *sched = NULL;
|
||||||
|
|
||||||
|
PRINTK("Now Alive EDF Thread:\n");
|
||||||
|
PRINTK("TID CurTime DeadTime FinishTime taskName\n");
|
||||||
|
|
||||||
|
for (UINT32 tid = 0; tid < g_taskMaxNum; tid++) {
|
||||||
|
LosTaskCB *taskCB = g_taskCBArray + tid;
|
||||||
|
SCHEDULER_LOCK(intSave);
|
||||||
|
if (OsTaskIsUnused(taskCB)) {
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sched = (SchedEDF *)&taskCB->sp;
|
||||||
|
if (sched->policy != LOS_SCHED_DEADLINE) {
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
(VOID)memcpy_s(&task, sizeof(LosTaskCB), taskCB, sizeof(LosTaskCB));
|
||||||
|
|
||||||
|
curTime = OS_SYS_CYCLE_TO_US(HalClockGetCycles());
|
||||||
|
finishTime = OS_SYS_CYCLE_TO_US(sched->finishTime);
|
||||||
|
deadline = OS_SYS_CYCLE_TO_US(taskCB->ops->deadlineGet(taskCB));
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
||||||
|
PRINTK("%3u%15llu%15llu%15llu %-32s\n",
|
||||||
|
task.taskID, curTime, deadline, finishTime, task.taskName);
|
||||||
|
}
|
||||||
|
|
||||||
|
OsEDFDebugPrint();
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -47,13 +47,13 @@
|
||||||
|
|
||||||
extern INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize);
|
extern INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize);
|
||||||
|
|
||||||
extern INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio);
|
extern INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio);
|
||||||
|
|
||||||
extern INT32 LOS_GetProcessPriority(INT32 pid);
|
extern INT32 LOS_GetProcessPriority(INT32 pid);
|
||||||
|
|
||||||
extern INT32 LOS_GetProcessScheduler(INT32 pid);
|
extern INT32 LOS_GetProcessScheduler(INT32 pid, INT32 *policy, LosSchedParam *schedParam);
|
||||||
|
|
||||||
extern INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, UINT16 prio);
|
extern INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, const LosSchedParam *schedParam);
|
||||||
|
|
||||||
extern UINT32 LOS_GetCurrProcessID(VOID);
|
extern UINT32 LOS_GetCurrProcessID(VOID);
|
||||||
|
|
||||||
|
|
|
@ -514,8 +514,21 @@ typedef struct tagTskInitParam {
|
||||||
UINT16 consoleID; /**< The console id of task belongs */
|
UINT16 consoleID; /**< The console id of task belongs */
|
||||||
UINTPTR processID;
|
UINTPTR processID;
|
||||||
UserTaskParam userParam;
|
UserTaskParam userParam;
|
||||||
|
/* edf parameters */
|
||||||
|
UINT32 runTimeUs;
|
||||||
|
UINT64 deadlineUs;
|
||||||
|
UINT64 periodUs;
|
||||||
} TSK_INIT_PARAM_S;
|
} TSK_INIT_PARAM_S;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
INT32 priority;
|
||||||
|
INT32 runTimeUs;
|
||||||
|
};
|
||||||
|
INT32 deadlineUs;
|
||||||
|
INT32 periodUs;
|
||||||
|
} LosSchedParam;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup los_task
|
* @ingroup los_task
|
||||||
* Task name length
|
* Task name length
|
||||||
|
|
|
@ -72,10 +72,10 @@ extern unsigned int SysGetGroupId(void);
|
||||||
extern unsigned int SysGetTid(void);
|
extern unsigned int SysGetTid(void);
|
||||||
extern void SysSchedYield(int type);
|
extern void SysSchedYield(int type);
|
||||||
extern int SysSchedGetScheduler(int id, int flag);
|
extern int SysSchedGetScheduler(int id, int flag);
|
||||||
extern int SysSchedSetScheduler(int id, int policy, int prio, int flag);
|
extern int SysSchedSetScheduler(int id, int policy, const LosSchedParam *userParam, int flag);
|
||||||
extern int SysSchedGetParam(int id, int flag);
|
extern int SysSchedGetParam(int id, LosSchedParam *userParam, int flag);
|
||||||
extern int SysSchedSetParam(int id, unsigned int prio, int flag);
|
extern int SysSchedSetParam(int id, const LosSchedParam *userParam, int flag);
|
||||||
extern int SysSetProcessPriority(int which, int who, unsigned int prio);
|
extern int SysSetProcessPriority(int which, int who, int prio);
|
||||||
extern int SysGetProcessPriority(int which, int who);
|
extern int SysGetProcessPriority(int which, int who);
|
||||||
extern int SysSchedGetPriorityMin(int policy);
|
extern int SysSchedGetPriorityMin(int policy);
|
||||||
extern int SysSchedGetPriorityMax(int policy);
|
extern int SysSchedGetPriorityMax(int policy);
|
||||||
|
|
|
@ -60,23 +60,44 @@ static int OsPermissionToCheck(unsigned int pid, unsigned int who)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OsUserTaskSchedulerSet(unsigned int tid, unsigned short policy, unsigned short priority, bool policyFlag)
|
static int UserTaskSchedulerCheck(unsigned int tid, int policy, const LosSchedParam *schedParam, bool policyFlag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int processPolicy;
|
||||||
|
|
||||||
|
if (OS_TID_CHECK_INVALID(tid)) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = OsSchedulerParamCheck(policy, TRUE, schedParam);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policyFlag) {
|
||||||
|
ret = LOS_GetProcessScheduler(LOS_GetCurrProcessID(), &processPolicy, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -ret;
|
||||||
|
}
|
||||||
|
if ((processPolicy != LOS_SCHED_DEADLINE) && (policy == LOS_SCHED_DEADLINE)) {
|
||||||
|
return EPERM;
|
||||||
|
} else if ((processPolicy == LOS_SCHED_DEADLINE) && (policy != LOS_SCHED_DEADLINE)) {
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int OsUserTaskSchedulerSet(unsigned int tid, int policy, const LosSchedParam *schedParam, bool policyFlag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int intSave;
|
unsigned int intSave;
|
||||||
bool needSched = false;
|
bool needSched = false;
|
||||||
SchedParam param = { 0 };
|
SchedParam param = { 0 };
|
||||||
|
|
||||||
if (OS_TID_CHECK_INVALID(tid)) {
|
ret = UserTaskSchedulerCheck(tid, policy, schedParam, policyFlag);
|
||||||
return EINVAL;
|
if (ret != 0) {
|
||||||
}
|
return ret;
|
||||||
|
|
||||||
if (priority > OS_TASK_PRIORITY_LOWEST) {
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((policy != LOS_SCHED_FIFO) && (policy != LOS_SCHED_RR)) {
|
|
||||||
return EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(tid);
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(tid);
|
||||||
|
@ -88,8 +109,22 @@ static int OsUserTaskSchedulerSet(unsigned int tid, unsigned short policy, unsig
|
||||||
}
|
}
|
||||||
|
|
||||||
taskCB->ops->schedParamGet(taskCB, ¶m);
|
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||||
param.policy = (policyFlag == true) ? policy : param.policy;
|
param.policy = (policyFlag == true) ? (UINT16)policy : param.policy;
|
||||||
param.priority = priority;
|
if ((param.policy == LOS_SCHED_RR) || (param.policy == LOS_SCHED_FIFO)) {
|
||||||
|
param.priority = schedParam->priority;
|
||||||
|
} else if (param.policy == LOS_SCHED_DEADLINE) {
|
||||||
|
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||||
|
/* user mode process with privilege of CAP_SCHED_SETPRIORITY can change the priority */
|
||||||
|
if (!IsCapPermit(CAP_SCHED_SETPRIORITY)) {
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
param.runTimeUs = schedParam->runTimeUs;
|
||||||
|
param.deadlineUs = schedParam->deadlineUs;
|
||||||
|
param.periodUs = schedParam->periodUs;
|
||||||
|
}
|
||||||
|
|
||||||
needSched = taskCB->ops->schedParamModify(taskCB, ¶m);
|
needSched = taskCB->ops->schedParamModify(taskCB, ¶m);
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
||||||
|
@ -113,6 +148,7 @@ int SysSchedGetScheduler(int id, int flag)
|
||||||
{
|
{
|
||||||
unsigned int intSave;
|
unsigned int intSave;
|
||||||
SchedParam param = { 0 };
|
SchedParam param = { 0 };
|
||||||
|
int policy;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (flag < 0) {
|
if (flag < 0) {
|
||||||
|
@ -137,43 +173,57 @@ int SysSchedGetScheduler(int id, int flag)
|
||||||
id = (int)LOS_GetCurrProcessID();
|
id = (int)LOS_GetCurrProcessID();
|
||||||
}
|
}
|
||||||
|
|
||||||
return LOS_GetProcessScheduler(id);
|
ret = LOS_GetProcessScheduler(id, &policy, NULL);
|
||||||
}
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
int SysSchedSetScheduler(int id, int policy, int prio, int flag)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (flag < 0) {
|
|
||||||
return -OsUserTaskSchedulerSet(id, policy, prio, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SysSchedSetScheduler(int id, int policy, const LosSchedParam *userParam, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
LosSchedParam param;
|
||||||
|
|
||||||
|
if (LOS_ArchCopyFromUser(¶m, userParam, sizeof(LosSchedParam)) != 0) {
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag < 0) {
|
||||||
|
return -OsUserTaskSchedulerSet(id, policy, ¶m, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policy == LOS_SCHED_RR) {
|
||||||
|
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||||
|
if (param.priority < OsPidLimitGetPriorityLimit()) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (param.priority < OS_USER_PROCESS_PRIORITY_HIGHEST) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
id = (int)LOS_GetCurrProcessID();
|
id = (int)LOS_GetCurrProcessID();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
|
||||||
if (prio < OsPidLimitGetPriorityLimit()) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = OsPermissionToCheck(id, LOS_GetCurrProcessID());
|
ret = OsPermissionToCheck(id, LOS_GetCurrProcessID());
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OsSetProcessScheduler(LOS_PRIO_PROCESS, id, prio, policy);
|
return OsSetProcessScheduler(LOS_PRIO_PROCESS, id, policy, ¶m);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SysSchedGetParam(int id, int flag)
|
int SysSchedGetParam(int id, LosSchedParam *userParam, int flag)
|
||||||
{
|
{
|
||||||
|
LosSchedParam schedParam = {0};
|
||||||
SchedParam param = { 0 };
|
SchedParam param = { 0 };
|
||||||
unsigned int intSave;
|
unsigned int intSave;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (flag < 0) {
|
if (flag < 0) {
|
||||||
if (OS_TID_CHECK_INVALID(id)) {
|
if (OS_TID_CHECK_INVALID(id)) {
|
||||||
|
@ -182,7 +232,7 @@ int SysSchedGetParam(int id, int flag)
|
||||||
|
|
||||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
|
||||||
SCHEDULER_LOCK(intSave);
|
SCHEDULER_LOCK(intSave);
|
||||||
int ret = OsUserTaskOperatePermissionsCheck(taskCB);
|
ret = OsUserTaskOperatePermissionsCheck(taskCB);
|
||||||
if (ret != LOS_OK) {
|
if (ret != LOS_OK) {
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
return -ret;
|
return -ret;
|
||||||
|
@ -190,9 +240,14 @@ int SysSchedGetParam(int id, int flag)
|
||||||
|
|
||||||
taskCB->ops->schedParamGet(taskCB, ¶m);
|
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
return (int)param.priority;
|
if (param.policy == LOS_SCHED_DEADLINE) {
|
||||||
|
schedParam.runTimeUs = param.runTimeUs;
|
||||||
|
schedParam.deadlineUs = param.deadlineUs;
|
||||||
|
schedParam.periodUs = param.periodUs;
|
||||||
|
} else {
|
||||||
|
schedParam.priority = param.priority;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
id = (int)LOS_GetCurrProcessID();
|
id = (int)LOS_GetCurrProcessID();
|
||||||
}
|
}
|
||||||
|
@ -201,14 +256,23 @@ int SysSchedGetParam(int id, int flag)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OsGetProcessPriority(LOS_PRIO_PROCESS, id);
|
ret = LOS_GetProcessScheduler(id, NULL, &schedParam);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOS_ArchCopyToUser(userParam, &schedParam, sizeof(LosSchedParam))) {
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SysSetProcessPriority(int which, int who, unsigned int prio)
|
int SysSetProcessPriority(int which, int who, int prio)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
|
if (which != LOS_PRIO_PROCESS) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +284,10 @@ int SysSetProcessPriority(int which, int who, unsigned int prio)
|
||||||
if (prio < OsPidLimitGetPriorityLimit()) {
|
if (prio < OsPidLimitGetPriorityLimit()) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = OsPermissionToCheck(who, LOS_GetCurrProcessID());
|
ret = OsPermissionToCheck(who, LOS_GetCurrProcessID());
|
||||||
|
@ -227,22 +295,31 @@ int SysSetProcessPriority(int which, int who, unsigned int prio)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OsSetProcessScheduler(which, who, prio, LOS_GetProcessScheduler(who));
|
return LOS_SetProcessPriority(who, prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SysSchedSetParam(int id, unsigned int prio, int flag)
|
int SysSchedSetParam(int id, const LosSchedParam *userParam, int flag)
|
||||||
{
|
{
|
||||||
|
int ret, policy;
|
||||||
|
LosSchedParam param;
|
||||||
|
|
||||||
if (flag < 0) {
|
if (flag < 0) {
|
||||||
return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, prio, false);
|
if (LOS_ArchCopyFromUser(¶m, userParam, sizeof(LosSchedParam)) != 0) {
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, ¶m, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
if (id == 0) {
|
||||||
if (prio < OsPidLimitGetPriorityLimit()) {
|
id = (int)LOS_GetCurrProcessID();
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return SysSetProcessPriority(LOS_PRIO_PROCESS, id, prio);
|
ret = LOS_GetProcessScheduler(id, &policy, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SysSchedSetScheduler(id, policy, userParam, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SysGetProcessPriority(int which, int who)
|
int SysGetProcessPriority(int which, int who)
|
||||||
|
|
|
@ -169,7 +169,7 @@ SYSCALL_HAND_DEF(__NR_sethostname, SysSetHostName, int, ARG_NUM_2)
|
||||||
SYSCALL_HAND_DEF(__NR_mprotect, SysMprotect, int, ARG_NUM_3)
|
SYSCALL_HAND_DEF(__NR_mprotect, SysMprotect, int, ARG_NUM_3)
|
||||||
SYSCALL_HAND_DEF(__NR_getpgid, SysGetProcessGroupID, int, ARG_NUM_1)
|
SYSCALL_HAND_DEF(__NR_getpgid, SysGetProcessGroupID, int, ARG_NUM_1)
|
||||||
SYSCALL_HAND_DEF(__NR_sched_setparam, SysSchedSetParam, int, ARG_NUM_3)
|
SYSCALL_HAND_DEF(__NR_sched_setparam, SysSchedSetParam, int, ARG_NUM_3)
|
||||||
SYSCALL_HAND_DEF(__NR_sched_getparam, SysSchedGetParam, int, ARG_NUM_2)
|
SYSCALL_HAND_DEF(__NR_sched_getparam, SysSchedGetParam, int, ARG_NUM_3)
|
||||||
SYSCALL_HAND_DEF(__NR_sched_setscheduler, SysSchedSetScheduler, int, ARG_NUM_4)
|
SYSCALL_HAND_DEF(__NR_sched_setscheduler, SysSchedSetScheduler, int, ARG_NUM_4)
|
||||||
SYSCALL_HAND_DEF(__NR_sched_getscheduler, SysSchedGetScheduler, int, ARG_NUM_2)
|
SYSCALL_HAND_DEF(__NR_sched_getscheduler, SysSchedGetScheduler, int, ARG_NUM_2)
|
||||||
SYSCALL_HAND_DEF(__NR_sched_yield, SysSchedYield, void, ARG_NUM_1)
|
SYSCALL_HAND_DEF(__NR_sched_yield, SysSchedYield, void, ARG_NUM_1)
|
||||||
|
|
|
@ -181,6 +181,9 @@ static int StartClients(pthread_t *cli, int cliNum)
|
||||||
for (int i = 0; i < cliNum; ++i) {
|
for (int i = 0; i < cliNum; ++i) {
|
||||||
ret = pthread_attr_init(&attr);
|
ret = pthread_attr_init(&attr);
|
||||||
param.sched_priority = param.sched_priority + 1;
|
param.sched_priority = param.sched_priority + 1;
|
||||||
|
if (param.sched_priority > 31) { /* 31: prio */
|
||||||
|
param.sched_priority = 31; /* 31: prio */
|
||||||
|
}
|
||||||
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
||||||
pthread_attr_setschedparam(&attr, ¶m);
|
pthread_attr_setschedparam(&attr, ¶m);
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ static int ProcessTest001(void)
|
||||||
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
ret = pthread_attr_init(&a);
|
ret = pthread_attr_init(&a);
|
||||||
param.sched_priority += 1;
|
param.sched_priority = 26; /* 26: prio */
|
||||||
pthread_attr_setschedparam(&a, ¶m);
|
pthread_attr_setschedparam(&a, ¶m);
|
||||||
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
|
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
|
||||||
ret = pthread_create(&newPthread, &a, ThreadFunc3, &data);
|
ret = pthread_create(&newPthread, &a, ThreadFunc3, &data);
|
||||||
|
|
|
@ -55,6 +55,14 @@ pthread_sources_smoke = [
|
||||||
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_017.cpp",
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_017.cpp",
|
||||||
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_018.cpp",
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_018.cpp",
|
||||||
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_019.cpp",
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_019.cpp",
|
||||||
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_020.cpp",
|
||||||
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_021.cpp",
|
||||||
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_022.cpp",
|
||||||
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_023.cpp",
|
||||||
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_024.cpp",
|
||||||
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_025.cpp",
|
||||||
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_026.cpp",
|
||||||
|
"$TEST_UNITTEST_DIR/process/basic/pthread/smoke/pthread_test_027.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
pthread_sources_full = [
|
pthread_sources_full = [
|
||||||
|
|
|
@ -74,6 +74,14 @@ extern void ItTestPthread016(void);
|
||||||
extern void ItTestPthread017(void);
|
extern void ItTestPthread017(void);
|
||||||
extern void ItTestPthread018(void);
|
extern void ItTestPthread018(void);
|
||||||
extern void ItTestPthread019(void);
|
extern void ItTestPthread019(void);
|
||||||
|
extern void ItTestPthread020(void);
|
||||||
|
extern void ItTestPthread021(void);
|
||||||
|
extern void ItTestPthread022(void);
|
||||||
|
extern void ItTestPthread023(void);
|
||||||
|
extern void ItTestPthread024(void);
|
||||||
|
extern void ItTestPthread025(void);
|
||||||
|
extern void ItTestPthread026(void);
|
||||||
|
extern void ItTestPthread027(void);
|
||||||
extern void ItTestPthreadAtfork001(void);
|
extern void ItTestPthreadAtfork001(void);
|
||||||
extern void ItTestPthreadAtfork002(void);
|
extern void ItTestPthreadAtfork002(void);
|
||||||
extern void ItTestPthreadOnce001(void);
|
extern void ItTestPthreadOnce001(void);
|
||||||
|
|
|
@ -186,6 +186,104 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread019, TestSize.Level0)
|
||||||
ItTestPthread019();
|
ItTestPthread019();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* @tc.name: it_test_pthread_020
|
||||||
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
* @tc.type: FUNC
|
||||||
|
* @tc.require: issueI6T3P3
|
||||||
|
* @tc.author:
|
||||||
|
*/
|
||||||
|
HWTEST_F(ProcessPthreadTest, ItTestPthread020, TestSize.Level0)
|
||||||
|
{
|
||||||
|
ItTestPthread020();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* @tc.name: it_test_pthread_021
|
||||||
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
* @tc.type: FUNC
|
||||||
|
* @tc.require: issueI6T3P3
|
||||||
|
* @tc.author:
|
||||||
|
*/
|
||||||
|
HWTEST_F(ProcessPthreadTest, ItTestPthread021, TestSize.Level0)
|
||||||
|
{
|
||||||
|
ItTestPthread021();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* @tc.name: it_test_pthread_022
|
||||||
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
* @tc.type: FUNC
|
||||||
|
* @tc.require: issueI6T3P3
|
||||||
|
* @tc.author:
|
||||||
|
*/
|
||||||
|
HWTEST_F(ProcessPthreadTest, ItTestPthread022, TestSize.Level0)
|
||||||
|
{
|
||||||
|
ItTestPthread022();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* @tc.name: it_test_pthread_024
|
||||||
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
* @tc.type: FUNC
|
||||||
|
* @tc.require: issueI6T3P3
|
||||||
|
* @tc.author:
|
||||||
|
*/
|
||||||
|
HWTEST_F(ProcessPthreadTest, ItTestPthread024, TestSize.Level0)
|
||||||
|
{
|
||||||
|
ItTestPthread024();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* @tc.name: it_test_pthread_026
|
||||||
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
* @tc.type: FUNC
|
||||||
|
* @tc.require: issueI6T3P3
|
||||||
|
* @tc.author:
|
||||||
|
*/
|
||||||
|
HWTEST_F(ProcessPthreadTest, ItTestPthread026, TestSize.Level0)
|
||||||
|
{
|
||||||
|
ItTestPthread026();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* @tc.name: it_test_pthread_027
|
||||||
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
* @tc.type: FUNC
|
||||||
|
* @tc.require: issueI6T3P3
|
||||||
|
* @tc.author:
|
||||||
|
*/
|
||||||
|
HWTEST_F(ProcessPthreadTest, ItTestPthread027, TestSize.Level0)
|
||||||
|
{
|
||||||
|
ItTestPthread027();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* @tc.name: it_test_pthread_023
|
||||||
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
* @tc.type: FUNC
|
||||||
|
* @tc.require: issueI6T3P3
|
||||||
|
* @tc.author:
|
||||||
|
*/
|
||||||
|
HWTEST_F(ProcessPthreadTest, ItTestPthread023, TestSize.Level0)
|
||||||
|
{
|
||||||
|
ItTestPthread023();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* *
|
||||||
|
* @tc.name: it_test_pthread_025
|
||||||
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
* @tc.type: FUNC
|
||||||
|
* @tc.require: issueI6T3P3
|
||||||
|
* @tc.author:
|
||||||
|
*/
|
||||||
|
HWTEST_F(ProcessPthreadTest, ItTestPthread025, TestSize.Level0)
|
||||||
|
{
|
||||||
|
ItTestPthread025();
|
||||||
|
}
|
||||||
|
|
||||||
/* *
|
/* *
|
||||||
* @tc.name: it_test_pthread_017
|
* @tc.name: it_test_pthread_017
|
||||||
* @tc.desc: function for ProcessPthreadTest
|
* @tc.desc: function for ProcessPthreadTest
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "it_pthread_test.h"
|
||||||
|
|
||||||
|
static int ChildProcess(void)
|
||||||
|
{
|
||||||
|
int ret, currPolicy = 0;
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
struct sched_param currSchedParam = { 0 };
|
||||||
|
struct sched_param param = {
|
||||||
|
.sched_deadline = 4000000, /* 4000000, 4s */
|
||||||
|
.sched_runtime = 200000, /* 200000, 200ms */
|
||||||
|
.sched_period = 5000000, /* 5000000, 5s */
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = sched_getparam(getpid(), &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
currPolicy = sched_getscheduler(getpid());
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_RR, LOS_NOK);
|
||||||
|
currSchedParam.sched_runtime = 0;
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 0, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 0, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 0, LOS_NOK);
|
||||||
|
|
||||||
|
ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
currPolicy = sched_getscheduler(getpid());
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK);
|
||||||
|
|
||||||
|
ret = sched_getparam(getpid(), &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 4000000, LOS_NOK); /* 4000000, 4s */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 200000, LOS_NOK); /* 200000, 200ms */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 5000000, LOS_NOK); /* 5000000, 5s */
|
||||||
|
|
||||||
|
printf("--- 1 edf thread start ---\n\r");
|
||||||
|
do {
|
||||||
|
for (volatile int i = 0; i < 100000; i++) { /* 100000, no special meaning */
|
||||||
|
for (volatile int j = 0; j < 10; j++) { /* 10, no special meaning */
|
||||||
|
int tmp = i - j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count % 20 == 0) { /* 20, no special meaning */
|
||||||
|
printf("--- 2 edf thread running ---\n\r");
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
} while (count <= 100); /* 100, no special meaning */
|
||||||
|
printf("--- 3 edf thread end ---\n\r");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestCase(void)
|
||||||
|
{
|
||||||
|
int ret, pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = ChildProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItTestPthread020(void)
|
||||||
|
{
|
||||||
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_020", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "it_pthread_test.h"
|
||||||
|
|
||||||
|
static void *ThreadFuncTest(void *args)
|
||||||
|
{
|
||||||
|
int pt = (int)args;
|
||||||
|
int ret, currPolicy;
|
||||||
|
struct sched_param currSchedParam;
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
int currTID = Syscall(SYS_gettid, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), & currPolicy, &currSchedParam);
|
||||||
|
ICUNIT_GOTO_EQUAL(ret, 0, LOS_NOK, EXIT);
|
||||||
|
ICUNIT_GOTO_EQUAL( currPolicy, SCHED_DEADLINE, LOS_NOK, EXIT);
|
||||||
|
ICUNIT_GOTO_EQUAL(currSchedParam.sched_deadline, 3000000, LOS_NOK, EXIT); /* 3000000, 3s */
|
||||||
|
ICUNIT_GOTO_EQUAL(currSchedParam.sched_runtime, 200000, LOS_NOK, EXIT); /* 200000, 200ms */
|
||||||
|
ICUNIT_GOTO_EQUAL(currSchedParam.sched_period, 5000000, LOS_NOK, EXIT); /* 5000000, 5s */
|
||||||
|
|
||||||
|
printf("--- 1 edf Tid[%d] PTid[%d] thread start ---\n\r", currTID, pt);
|
||||||
|
do {
|
||||||
|
for (volatile int i = 0; i < 100000; i++) { /* 100000, no special meaning */
|
||||||
|
for (volatile int j = 0; j < 5; j++) { /* 5, no special meaning */
|
||||||
|
volatile int tmp = i - j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count % 20 == 0) { /* 20, no special meaning */
|
||||||
|
printf("--- 2 edf Tid[%d] PTid[%d] thread running ---\n\r", currTID, pt);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
} while (count <= 100); /* 100, no special meaning */
|
||||||
|
printf("--- 3 edf Tid[%d] PTid[%d] thread end ---\n\r", currTID, pt);
|
||||||
|
|
||||||
|
ret = LOS_OK;
|
||||||
|
return (void *)(&ret);
|
||||||
|
EXIT:
|
||||||
|
ret = LOS_NOK;
|
||||||
|
return (void *)(&ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ChildProcess(void)
|
||||||
|
{
|
||||||
|
int *childThreadRetval = nullptr;
|
||||||
|
pthread_t newUserThread;
|
||||||
|
int ret, currPolicy = 0;
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
struct sched_param currSchedParam = { 0 };
|
||||||
|
int currTID = Syscall(SYS_gettid, 0, 0, 0, 0);
|
||||||
|
struct sched_param param = {
|
||||||
|
.sched_deadline = 3000000, /* 3000000, 3s */
|
||||||
|
.sched_runtime = 200000, /* 200000, 200ms */
|
||||||
|
.sched_period = 5000000, /* 5000000, 5s */
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), & currPolicy, &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 3000000, LOS_NOK); /* 3000000, 3s */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 200000, LOS_NOK); /* 200000, 200ms */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 5000000, LOS_NOK); /* 5000000, 5s */
|
||||||
|
|
||||||
|
ret = pthread_create(&newUserThread, NULL, ThreadFuncTest, (void *)currTID);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
printf("--- 1 edf Tid[%d] thread start ---\n\r", currTID);
|
||||||
|
do {
|
||||||
|
for (volatile int i = 0; i < 100000; i++) { /* 100000, no special meaning */
|
||||||
|
for (volatile int j = 0; j < 5; j++) { /* 5, no special meaning */
|
||||||
|
int tmp = i - j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count % 20 == 0) { /* 20, no special meaning */
|
||||||
|
printf("--- 2 edf Tid[%d] thread running ---\n\r", currTID);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
} while (count <= 100); /* 100, no special meaning */
|
||||||
|
printf("--- 3 edf Tid[%d] thread end ---\n\r", currTID);
|
||||||
|
|
||||||
|
ret = pthread_join(newUserThread, (void **)&childThreadRetval);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
ICUNIT_ASSERT_EQUAL(*childThreadRetval, 0, *childThreadRetval);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestCase(void)
|
||||||
|
{
|
||||||
|
int ret, pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = ChildProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItTestPthread021(void)
|
||||||
|
{
|
||||||
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_021", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "it_pthread_test.h"
|
||||||
|
|
||||||
|
static int EdfProcess(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int currPolicy = 0;
|
||||||
|
struct sched_param currSchedParam = { 0 };
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
int currTID = Syscall(SYS_gettid, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), &currPolicy, &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 3000000, LOS_NOK); /* 3000000, 3s */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 200000, LOS_NOK); /* 200000, 200ms */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 5000000, LOS_NOK); /* 5000000, 5s */
|
||||||
|
|
||||||
|
printf("--- edf2 -- 1 -- Tid[%d] thread start ---\n\r", currTID);
|
||||||
|
do {
|
||||||
|
for (volatile int i = 0; i < 100000; i++) { /* 100000, no special meaning */
|
||||||
|
for (volatile int j = 0; j < 5; j++) { /* 5, no special meaning */
|
||||||
|
int tmp = i - j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count % 20 == 0) { /* 20, no special meaning */
|
||||||
|
printf("--- edf2 -- 2 -- Tid[%d] thread running ---\n\r", currTID);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
} while (count <= 100); /* 100, no special meaning */
|
||||||
|
printf("--- edf2 -- 3 -- Tid[%d] thread end ---\n\r", currTID);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ChildProcess(void)
|
||||||
|
{
|
||||||
|
int *childThreadRetval = nullptr;
|
||||||
|
pthread_t newUserThread;
|
||||||
|
int pid, status, ret;
|
||||||
|
int currPolicy = 0;
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
struct sched_param currSchedParam = { 0 };
|
||||||
|
int currTID = Syscall(SYS_gettid, 0, 0, 0, 0);
|
||||||
|
struct sched_param param = {
|
||||||
|
.sched_deadline = 3000000, /* 3000000, 3s */
|
||||||
|
.sched_runtime = 200000, /* 200000, 200ms */
|
||||||
|
.sched_period = 5000000, /* 5000000, 5s */
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), &currPolicy, &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 3000000, LOS_NOK); /* 3000000, 3s */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 200000, LOS_NOK); /* 200000, 200ms */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 5000000, LOS_NOK); /* 5000000, 5s */
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = EdfProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
printf("--- edf1 -- 1 -- Tid[%d] thread start ---\n\r", currTID);
|
||||||
|
do {
|
||||||
|
for (volatile int i = 0; i < 500000; i++) { /* 500000, no special meaning */
|
||||||
|
int tmp = i + 1;
|
||||||
|
}
|
||||||
|
if (count % 20 == 0) { /* 20, no special meaning */
|
||||||
|
printf("--- edf1 -- 2 -- Tid[%d] thread running ---\n\r", currTID);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
} while (count <= 100); /* 100, no special meaning */
|
||||||
|
printf("--- edf1 -- 3 -- Tid[%d] thread end ---\n\r", currTID);
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestCase(void)
|
||||||
|
{
|
||||||
|
int ret, pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = ChildProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItTestPthread022(void)
|
||||||
|
{
|
||||||
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_022", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "it_pthread_test.h"
|
||||||
|
|
||||||
|
static void *ThreadFuncTest(void *args)
|
||||||
|
{
|
||||||
|
return (void *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ChildProcess(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int currPolicy = 0;
|
||||||
|
int oldPolicy;
|
||||||
|
pthread_t newUserThread;
|
||||||
|
pthread_attr_t a = { 0 };
|
||||||
|
struct sched_param hpfparam = { 0 };
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
struct sched_param currSchedParam = { 0 };
|
||||||
|
int currTID = Syscall(SYS_gettid, 0, 0, 0, 0);
|
||||||
|
struct sched_param param = {
|
||||||
|
.sched_deadline = 3000000, /* 3000000, 3s */
|
||||||
|
.sched_runtime = 200000, /* 200000, 200ms */
|
||||||
|
.sched_period = 5000000, /* 5000000, 5s */
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), &oldPolicy, &hpfparam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
|
||||||
|
|
||||||
|
ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), &currPolicy, &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 3000000, LOS_NOK); /* 3000000, 3s */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 200000, LOS_NOK); /* 200000, 200ms */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 5000000, LOS_NOK); /* 5000000, 5s */
|
||||||
|
|
||||||
|
ret = pthread_attr_init(&a);
|
||||||
|
pthread_attr_setschedpolicy(&a, SCHED_RR);
|
||||||
|
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
|
||||||
|
ret = pthread_create(&newUserThread, &a, ThreadFuncTest, NULL);
|
||||||
|
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
printf("--- edf2 -- 1 -- Tid[%d] thread end ---\n\r", currTID);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestCase(void)
|
||||||
|
{
|
||||||
|
int ret, pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = ChildProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItTestPthread023(void)
|
||||||
|
{
|
||||||
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_023", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "it_pthread_test.h"
|
||||||
|
|
||||||
|
static void *ThreadFuncTest(void *args)
|
||||||
|
{
|
||||||
|
(void)args;
|
||||||
|
printf("hpf thread run...\r\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ChildProcess(void)
|
||||||
|
{
|
||||||
|
int ret, currThreadPolicy;
|
||||||
|
pthread_attr_t a = { 0 };
|
||||||
|
struct sched_param hpfparam = { 0 };
|
||||||
|
pthread_t newUserThread;
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
int currTID = Syscall(SYS_gettid, 0, 0, 0, 0);
|
||||||
|
struct sched_param param = {
|
||||||
|
.sched_deadline = 3000000, /* 3000000, 3s */
|
||||||
|
.sched_runtime = 200000, /* 200000, 200ms */
|
||||||
|
.sched_period = 5000000, /* 5000000, 5s */
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, &hpfparam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
|
||||||
|
ret = pthread_attr_init(&a);
|
||||||
|
hpfparam.sched_priority = hpfparam.sched_priority - 1;
|
||||||
|
pthread_attr_setschedparam(&a, &hpfparam);
|
||||||
|
ret = pthread_create(&newUserThread, &a, ThreadFuncTest, (void *)currTID);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestCase(void)
|
||||||
|
{
|
||||||
|
int ret, pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = ChildProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItTestPthread024(void)
|
||||||
|
{
|
||||||
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_024", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "it_pthread_test.h"
|
||||||
|
|
||||||
|
static void *ThreadFuncTest(void *args)
|
||||||
|
{
|
||||||
|
(void)args;
|
||||||
|
printf("hpf thread run...\r\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ChildProcess(void)
|
||||||
|
{
|
||||||
|
int currThreadPolicy;
|
||||||
|
pthread_attr_t a = { 0 };
|
||||||
|
struct sched_param hpfparam = { 0 };
|
||||||
|
int *childThreadRetval = nullptr;
|
||||||
|
pthread_t newUserThread;
|
||||||
|
int ret;
|
||||||
|
int currPolicy = 0;
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
struct sched_param currSchedParam = { 0 };
|
||||||
|
int currTID = Syscall(SYS_gettid, 0, 0, 0, 0);
|
||||||
|
struct sched_param param = {
|
||||||
|
.sched_deadline = 3000000, /* 3000000, 3s */
|
||||||
|
.sched_runtime = 200000, /* 200000, 200ms */
|
||||||
|
.sched_period = 5000000, /* 5000000, 5s */
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, &hpfparam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
|
||||||
|
ret = pthread_attr_init(&a);
|
||||||
|
hpfparam.sched_priority = hpfparam.sched_priority - 1;
|
||||||
|
pthread_attr_setschedparam(&a, &hpfparam);
|
||||||
|
ret = pthread_create(&newUserThread, &a, ThreadFuncTest, (void *)currTID);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = pthread_join(newUserThread, NULL);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestCase(void)
|
||||||
|
{
|
||||||
|
int ret, pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = ChildProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItTestPthread025(void)
|
||||||
|
{
|
||||||
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_025", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "it_pthread_test.h"
|
||||||
|
|
||||||
|
static int ChildProcess(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int currPolicy = 0;
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
struct sched_param currSchedParam = { 0 };
|
||||||
|
struct sched_param param = {
|
||||||
|
.sched_deadline = 4000000, /* 4000000, 4s */
|
||||||
|
.sched_runtime = 200000, /* 200000, 200ms */
|
||||||
|
.sched_period = 5000000, /* 5000000, 5s */
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = sched_getparam(getpid(), &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
currPolicy = sched_getscheduler(getpid());
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_RR, LOS_NOK);
|
||||||
|
currSchedParam.sched_runtime = 0;
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 0, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 0, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 0, LOS_NOK);
|
||||||
|
|
||||||
|
ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
currPolicy = sched_getscheduler(getpid());
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK);
|
||||||
|
|
||||||
|
ret = sched_getparam(getpid(), &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 4000000, LOS_NOK); /* 4000000, 4s */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 200000, LOS_NOK); /* 200000, 200ms */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 5000000, LOS_NOK); /* 5000000, 5s */
|
||||||
|
|
||||||
|
printf("--- 1 edf thread start ---\n\r");
|
||||||
|
do {
|
||||||
|
for (volatile int i = 0; i < 100000; i++) { /* 100000, no special meaning */
|
||||||
|
for (volatile int j = 0; j < 10; j++) { /* 10, no special meaning */
|
||||||
|
int tmp = i - j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count % 20 == 0) { /* 20, no special meaning */
|
||||||
|
printf("--- 2 edf thread running ---\n\r");
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
} while (count <= 100); /* 100, no special meaning */
|
||||||
|
printf("--- 3 edf thread end ---\n\r");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestCase(void)
|
||||||
|
{
|
||||||
|
int ret, pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = ChildProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItTestPthread026(void)
|
||||||
|
{
|
||||||
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_026", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "it_pthread_test.h"
|
||||||
|
|
||||||
|
static int ChildProcess(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int currPolicy = 0;
|
||||||
|
volatile unsigned int count = 0;
|
||||||
|
struct sched_param currSchedParam = { 0 };
|
||||||
|
struct sched_param param = {
|
||||||
|
.sched_deadline = 4000000, /* 4000000, 4s */
|
||||||
|
.sched_runtime = 200000, /* 200000, 200ms */
|
||||||
|
.sched_period = 5000000, /* 5000000, 5s */
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = sched_getparam(getpid(), &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
currPolicy = sched_getscheduler(getpid());
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_RR, LOS_NOK);
|
||||||
|
currSchedParam.sched_runtime = 0;
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 0, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 0, LOS_NOK);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 0, LOS_NOK);
|
||||||
|
|
||||||
|
ret = sched_setscheduler(getpid(), SCHED_DEADLINE, ¶m);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
|
||||||
|
currPolicy = sched_getscheduler(getpid());
|
||||||
|
ICUNIT_ASSERT_EQUAL(currPolicy, SCHED_DEADLINE, LOS_NOK);
|
||||||
|
|
||||||
|
ret = sched_getparam(getpid(), &currSchedParam);
|
||||||
|
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_deadline, 4000000, LOS_NOK); /* 4000000, 4s */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_runtime, 200000, LOS_NOK); /* 200000, 200ms */
|
||||||
|
ICUNIT_ASSERT_EQUAL(currSchedParam.sched_period, 5000000, LOS_NOK); /* 5000000, 5s */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestCase(void)
|
||||||
|
{
|
||||||
|
int ret, pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
ret = ChildProcess();
|
||||||
|
if (ret != 0) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
} else if (pid > 0) {
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
} else {
|
||||||
|
exit(__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(status) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItTestPthread027(void)
|
||||||
|
{
|
||||||
|
TEST_ADD_CASE("IT_POSIX_PTHREAD_027", TestCase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
|
||||||
|
}
|
Loading…
Reference in New Issue