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
|
||||
help
|
||||
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
|
||||
bool "Enable user init Debug"
|
||||
default n
|
||||
|
|
|
@ -76,6 +76,7 @@ kernel_module(module_name) {
|
|||
"mp/los_percpu.c",
|
||||
"mp/los_spinlock.c",
|
||||
"om/los_err.c",
|
||||
"sched/los_deadline.c",
|
||||
"sched/los_idle.c",
|
||||
"sched/los_priority.c",
|
||||
"sched/los_sched.c",
|
||||
|
|
|
@ -939,7 +939,37 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
|
|||
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)) {
|
||||
return LOS_EINVAL;
|
||||
|
@ -949,19 +979,11 @@ STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 p
|
|||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (prio > OS_PROCESS_PRIORITY_LOWEST) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (policy != LOS_SCHED_RR) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
return OsSchedulerParamCheck(policy, FALSE, param);
|
||||
}
|
||||
|
||||
#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();
|
||||
|
||||
|
@ -971,7 +993,7 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedPa
|
|||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -983,12 +1005,13 @@ STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedPa
|
|||
}
|
||||
#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 };
|
||||
BOOL needSched = FALSE;
|
||||
UINT32 intSave;
|
||||
|
||||
INT32 ret = OsProcessSchedlerParamCheck(which, pid, prio, policy);
|
||||
INT32 ret = ProcessSchedulerParamCheck(which, pid, policy, schedParam);
|
||||
if (ret != LOS_OK) {
|
||||
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);
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (OsProcessIsInactive(processCB)) {
|
||||
ret = LOS_ESRCH;
|
||||
goto EXIT;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -LOS_ESRCH;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
if (!OsProcessCapPermitCheck(processCB, ¶m, prio)) {
|
||||
ret = LOS_EPERM;
|
||||
goto EXIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
LosTaskCB *taskCB = processCB->threadGroup;
|
||||
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);
|
||||
|
||||
LOS_MpSchedule(OS_MP_CPU_ALL);
|
||||
|
@ -1019,25 +1065,26 @@ LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio
|
|||
LOS_Schedule();
|
||||
}
|
||||
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;
|
||||
SchedParam param = { 0 };
|
||||
|
||||
if (OS_PID_CHECK_INVALID(pid)) {
|
||||
return -LOS_EINVAL;
|
||||
}
|
||||
|
||||
if ((policy == NULL) && (schedParam == NULL)) {
|
||||
return -LOS_EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
|
||||
if (OsProcessIsUnused(processCB)) {
|
||||
|
@ -1045,14 +1092,48 @@ LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid)
|
|||
return -LOS_ESRCH;
|
||||
}
|
||||
|
||||
LosTaskCB *taskCB = processCB->threadGroup;
|
||||
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||
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)
|
||||
|
@ -1079,6 +1160,11 @@ LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
|
|||
LosTaskCB *taskCB = processCB->threadGroup;
|
||||
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||
|
||||
if (param.policy == LOS_SCHED_DEADLINE) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -LOS_EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return param.basePrio;
|
||||
}
|
||||
|
@ -1850,6 +1936,38 @@ STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
|
|||
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)
|
||||
{
|
||||
LosTaskCB *runTask = OsCurrTaskGet();
|
||||
|
@ -1857,28 +1975,8 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR
|
|||
UINT32 ret, taskID, intSave;
|
||||
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.policy = param.policy;
|
||||
taskParam.usTaskPrio = param.priority;
|
||||
taskParam.processID = (UINTPTR)childProcessCB;
|
||||
GetCopyTaskParam(childProcessCB, entry, size, &taskParam, ¶m);
|
||||
|
||||
ret = LOS_TaskCreateOnly(&taskID, &taskParam);
|
||||
if (ret != LOS_OK) {
|
||||
|
|
|
@ -543,6 +543,7 @@ STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
|
|||
UINT32 ret;
|
||||
UINT32 numCount;
|
||||
SchedParam schedParam = { 0 };
|
||||
LosSchedParam initSchedParam = {0};
|
||||
UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy;
|
||||
|
||||
TaskCBBaseInit(taskCB, initParam);
|
||||
|
@ -553,7 +554,14 @@ STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
|
|||
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) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1365,6 +1373,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
|
|||
UINT32 taskID;
|
||||
UINT32 ret;
|
||||
UINT32 intSave;
|
||||
INT32 policy;
|
||||
SchedParam param;
|
||||
|
||||
ret = OsCreateUserTaskParamCheck(processID, initParam);
|
||||
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->usTaskPrio = OS_TASK_PRIORITY_LOWEST;
|
||||
initParam->policy = LOS_SCHED_RR;
|
||||
if (processID == OS_INVALID_VALUE) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *processCB = OsCurrProcessGet();
|
||||
initParam->processID = (UINTPTR)processCB;
|
||||
initParam->consoleID = processCB->consoleID;
|
||||
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 {
|
||||
initParam->policy = LOS_SCHED_RR;
|
||||
initParam->processID = processID;
|
||||
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 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize);
|
||||
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 LosProcessCB *OsGetUserInitProcess(VOID);
|
||||
extern LosProcessCB *OsGetIdleProcess(VOID);
|
||||
|
@ -553,6 +553,7 @@ extern VOID OsProcessThreadGroupDestroy(VOID);
|
|||
extern UINT32 OsGetProcessGroupCB(UINT32 pid, UINTPTR *ppgroupLeader);
|
||||
extern LosProcessCB *OsGetDefaultProcessCB(VOID);
|
||||
extern ProcessGroup *OsCreateProcessGroup(LosProcessCB *processCB);
|
||||
INT32 OsSchedulerParamCheck(UINT16 policy, BOOL isThread, const LosSchedParam *param);
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
|
|
|
@ -68,6 +68,10 @@ extern "C" {
|
|||
#define OS_SCHED_TICK_TO_CYCLE(ticks) ((UINT64)ticks * OS_CYCLE_PER_TICK)
|
||||
#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;
|
||||
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
|
||||
#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK)
|
||||
|
@ -98,9 +102,16 @@ typedef struct {
|
|||
UINT32 queueBitmap;
|
||||
} HPFRunqueue;
|
||||
|
||||
typedef struct {
|
||||
LOS_DL_LIST root;
|
||||
LOS_DL_LIST waitList;
|
||||
UINT64 period;
|
||||
} EDFRunqueue;
|
||||
|
||||
typedef struct {
|
||||
SortLinkAttribute timeoutQueue; /* task timeout queue */
|
||||
HPFRunqueue *hpfRunqueue;
|
||||
EDFRunqueue *edfRunqueue;
|
||||
UINT64 responseTime; /* Response time for current CPU tick interrupts */
|
||||
UINT32 responseID; /* The response ID of the current CPU tick interrupt */
|
||||
LosTaskCB *idleTask; /* idle task id */
|
||||
|
@ -212,30 +223,52 @@ STATIC INLINE VOID OsSchedRunqueuePendingSet(VOID)
|
|||
OsSchedRunqueue()->schedFlag |= INT_PEND_RESCH;
|
||||
}
|
||||
|
||||
#define LOS_SCHED_NORMAL 0U
|
||||
#define LOS_SCHED_FIFO 1U
|
||||
#define LOS_SCHED_RR 2U
|
||||
#define LOS_SCHED_IDLE 3U
|
||||
#define LOS_SCHED_NORMAL 0U
|
||||
#define LOS_SCHED_FIFO 1U
|
||||
#define LOS_SCHED_RR 2U
|
||||
#define LOS_SCHED_IDLE 3U
|
||||
#define LOS_SCHED_DEADLINE 6U
|
||||
|
||||
typedef struct {
|
||||
UINT16 policy;
|
||||
/* HPF scheduling parameters */
|
||||
UINT16 basePrio;
|
||||
UINT16 priority;
|
||||
UINT32 timeSlice;
|
||||
|
||||
/* EDF scheduling parameters */
|
||||
INT32 runTimeUs;
|
||||
UINT32 deadlineUs;
|
||||
UINT32 periodUs;
|
||||
} SchedParam;
|
||||
|
||||
typedef struct {
|
||||
UINT16 policy; /* This field must be present for all scheduling policies and must be the first in the structure */
|
||||
UINT16 basePrio;
|
||||
UINT16 priority;
|
||||
UINT32 initTimeSlice;
|
||||
UINT32 priBitmap; /**< Bitmap for recording the change of task priority, the priority can not be greater than 31 */
|
||||
UINT32 initTimeSlice; /* cycle */
|
||||
UINT32 priBitmap; /* Bitmap for recording the change of task priority, the priority can not be greater than 31 */
|
||||
} 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 {
|
||||
union {
|
||||
SchedEDF edf;
|
||||
SchedHPF hpf;
|
||||
} Policy;
|
||||
};
|
||||
} SchedPolicy;
|
||||
|
||||
typedef struct {
|
||||
|
@ -243,6 +276,7 @@ typedef struct {
|
|||
VOID (*enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB);
|
||||
VOID (*start)(SchedRunqueue *rq, LosTaskCB *taskCB);
|
||||
VOID (*exit)(LosTaskCB *taskCB);
|
||||
UINT64 (*waitTimeGet)(LosTaskCB *taskCB);
|
||||
UINT32 (*wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout);
|
||||
VOID (*wake)(LosTaskCB *taskCB);
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return (LosTaskCB *)ArchCurrTaskGet();
|
||||
|
@ -623,6 +663,16 @@ STATIC INLINE VOID SchedTaskUnfreeze(LosTaskCB *taskCB)
|
|||
BOOL OsSchedLimitCheckTime(LosTaskCB *task);
|
||||
#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)
|
||||
{
|
||||
LosTaskCB *newTask = NULL;
|
||||
|
@ -660,9 +710,16 @@ STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq)
|
|||
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 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 IdleTaskSchedParamInit(LosTaskCB *taskCB);
|
||||
|
@ -670,7 +727,8 @@ VOID IdleTaskSchedParamInit(LosTaskCB *taskCB);
|
|||
INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2);
|
||||
VOID OsSchedPriorityInheritance(LosTaskCB *owner, const SchedParam *param);
|
||||
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 OsSchedResponseTimeReset(UINT64 responseTime);
|
||||
|
|
|
@ -57,9 +57,11 @@ typedef struct {
|
|||
#ifdef LOSCFG_SCHED_TICK_DEBUG
|
||||
VOID OsSchedDebugRecordData(VOID);
|
||||
UINT32 OsShellShowTickResponse(VOID);
|
||||
UINT32 OsShellShowSchedStatistics(VOID);
|
||||
UINT32 OsSchedDebugInit(VOID);
|
||||
#endif
|
||||
UINT32 OsShellShowSchedStatistics(VOID);
|
||||
UINT32 OsShellShowEdfSchedStatistics(VOID);
|
||||
VOID EDFDebugRecord(UINTPTR *taskCB, UINT64 oldFinish);
|
||||
#endif
|
||||
|
||||
#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_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
|
||||
* The maximum length of name.
|
||||
|
|
|
@ -53,6 +53,9 @@
|
|||
#include "los_sched_pri.h"
|
||||
#include "los_swtmr_pri.h"
|
||||
#include "los_info_pri.h"
|
||||
#ifdef LOSCFG_SCHED_DEBUG
|
||||
#include "los_statistics_pri.h"
|
||||
#endif
|
||||
|
||||
#define OS_PROCESS_MEM_INFO 0x2U
|
||||
#undef SHOW
|
||||
|
@ -93,6 +96,8 @@ STATIC UINT8 *ConvertSchedPolicyToString(UINT16 policy)
|
|||
return (UINT8 *)"RR";
|
||||
} else if (policy == LOS_SCHED_FIFO) {
|
||||
return (UINT8 *)"FIFO";
|
||||
} else if (policy == LOS_SCHED_DEADLINE) {
|
||||
return (UINT8 *)"EDF";
|
||||
} else if (policy == LOS_SCHED_IDLE) {
|
||||
return (UINT8 *)"IDLE";
|
||||
}
|
||||
|
@ -200,12 +205,10 @@ STATIC UINT8 *ConvertTaskStatusToString(UINT16 taskStatus)
|
|||
return (UINT8 *)"Suspended";
|
||||
} else if (taskStatus & OS_TASK_STATUS_DELAY) {
|
||||
return (UINT8 *)"Delay";
|
||||
} else if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
|
||||
return (UINT8 *)"PendTime";
|
||||
} else if (taskStatus & OS_TASK_STATUS_PENDING) {
|
||||
if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
|
||||
return (UINT8 *)"PendTime";
|
||||
} else {
|
||||
return (UINT8 *)"Pending";
|
||||
}
|
||||
return (UINT8 *)"Pending";
|
||||
} else if (taskStatus & OS_TASK_STATUS_EXIT) {
|
||||
return (UINT8 *)"Exit";
|
||||
}
|
||||
|
@ -413,11 +416,20 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv)
|
|||
}
|
||||
goto TASK_HELP;
|
||||
#endif
|
||||
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||
} else if (strcmp("-t", argv[0]) == 0) {
|
||||
if (!OsShellShowSchedStatistics()) {
|
||||
return LOS_OK;
|
||||
}
|
||||
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
|
||||
} else {
|
||||
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 = {
|
||||
.dequeue = IdleDequeue,
|
||||
.enqueue = IdleEnqueue,
|
||||
.waitTimeGet = NULL,
|
||||
.wait = IdleWait,
|
||||
.wake = IdleWake,
|
||||
.schedParamModify = NULL,
|
||||
|
|
|
@ -47,6 +47,7 @@ STATIC HPFRunqueue g_schedHPF;
|
|||
|
||||
STATIC VOID HPFDequeue(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 VOID HPFWake(LosTaskCB *resumedTask);
|
||||
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 = {
|
||||
.dequeue = HPFDequeue,
|
||||
.enqueue = HPFEnqueue,
|
||||
.waitTimeGet = HPFWaitTimeGet,
|
||||
.wait = HPFWait,
|
||||
.wake = HPFWake,
|
||||
.schedParamModify = HPFSchedParamModify,
|
||||
|
@ -94,7 +96,7 @@ STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 curr
|
|||
|
||||
if (sched->policy == LOS_SCHED_RR) {
|
||||
taskCB->timeSlice -= incTime;
|
||||
#ifdef LOSCFG_SCHED_DEBUG
|
||||
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||
taskCB->schedStat.timeSliceRealTime += incTime;
|
||||
#endif
|
||||
}
|
||||
|
@ -107,7 +109,7 @@ STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 curr
|
|||
rq->schedFlag |= INT_PEND_RESCH;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SCHED_DEBUG
|
||||
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||
taskCB->schedStat.allRuntime += incTime;
|
||||
#endif
|
||||
}
|
||||
|
@ -215,7 +217,7 @@ STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB)
|
|||
sched->initTimeSlice = TimeSliceCalculate(rq, sched->basePrio, sched->priority);
|
||||
taskCB->timeSlice = sched->initTimeSlice;
|
||||
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.timeSliceCount++;
|
||||
#endif
|
||||
|
@ -244,7 +246,7 @@ STATIC INLINE VOID PriQueInsert(HPFRunqueue *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)) {
|
||||
taskCB->startTime = OsGetCurrSchedTimeCycle();
|
||||
}
|
||||
|
@ -301,6 +303,12 @@ STATIC UINT32 HPFDelay(LosTaskCB *runTask, UINT64 waitTime)
|
|||
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)
|
||||
{
|
||||
runTask->taskStatus |= OS_TASK_STATUS_PENDING;
|
||||
|
@ -333,7 +341,7 @@ STATIC VOID HPFWake(LosTaskCB *resumedTask)
|
|||
}
|
||||
|
||||
if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPENDED)) {
|
||||
#ifdef LOSCFG_SCHED_DEBUG
|
||||
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||
resumedTask->schedStat.pendTime += OsGetCurrSchedTimeCycle() - resumedTask->startTime;
|
||||
resumedTask->schedStat.pendCount++;
|
||||
#endif
|
||||
|
@ -508,13 +516,13 @@ STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const
|
|||
|
||||
VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
|
||||
const SchedParam *parentParam,
|
||||
const TSK_INIT_PARAM_S *param)
|
||||
const LosSchedParam *param)
|
||||
{
|
||||
SchedHPF *sched = (SchedHPF *)&taskCB->sp;
|
||||
|
||||
sched->policy = policy;
|
||||
if (param != NULL) {
|
||||
sched->priority = param->usTaskPrio;
|
||||
sched->priority = param->priority;
|
||||
} else {
|
||||
sched->priority = parentParam->priority;
|
||||
}
|
||||
|
|
|
@ -102,15 +102,26 @@ VOID OsSchedExpireTimeUpdate(VOID)
|
|||
|
||||
STATIC INLINE VOID SchedTimeoutTaskWake(SchedRunqueue *rq, UINT64 currTime, LosTaskCB *taskCB, BOOL *needSched)
|
||||
{
|
||||
#ifndef LOSCFG_SCHED_DEBUG
|
||||
(VOID)currTime;
|
||||
#endif
|
||||
|
||||
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;
|
||||
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);
|
||||
if (tempStatus & OS_TASK_STATUS_PENDING) {
|
||||
if (tempStatus & OS_TASK_STATUS_PEND_TIME) {
|
||||
taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT;
|
||||
LOS_ListDelete(&taskCB->pendList);
|
||||
taskCB->taskMux = NULL;
|
||||
|
@ -118,7 +129,7 @@ STATIC INLINE VOID SchedTimeoutTaskWake(SchedRunqueue *rq, UINT64 currTime, LosT
|
|||
}
|
||||
|
||||
if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) {
|
||||
#ifdef LOSCFG_SCHED_DEBUG
|
||||
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||
taskCB->schedStat.pendTime += currTime - taskCB->startTime;
|
||||
taskCB->schedStat.pendCount++;
|
||||
#endif
|
||||
|
@ -212,8 +223,10 @@ VOID OsSchedRunqueueIdleInit(LosTaskCB *idleTask)
|
|||
|
||||
UINT32 OsSchedInit(VOID)
|
||||
{
|
||||
for (UINT16 cpuId = 0; cpuId < LOSCFG_KERNEL_CORE_NUM; cpuId++) {
|
||||
HPFSchedPolicyInit(OsSchedRunqueueByID(cpuId));
|
||||
for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
|
||||
SchedRunqueue *rq = OsSchedRunqueueByID(cpuid);
|
||||
EDFSchedPolicyInit(rq);
|
||||
HPFSchedPolicyInit(rq);
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SCHED_TICK_DEBUG
|
||||
|
@ -247,13 +260,15 @@ INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2)
|
|||
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) {
|
||||
case LOS_SCHED_FIFO:
|
||||
case LOS_SCHED_RR:
|
||||
HPFTaskSchedParamInit(taskCB, policy, parentParam, param);
|
||||
break;
|
||||
case LOS_SCHED_DEADLINE:
|
||||
return EDFTaskSchedParamInit(taskCB, policy, parentParam, param);
|
||||
case LOS_SCHED_IDLE:
|
||||
IdleTaskSchedParamInit(taskCB);
|
||||
break;
|
||||
|
@ -271,6 +286,9 @@ VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param)
|
|||
case LOS_SCHED_RR:
|
||||
HPFProcessDefaultSchedParamGet(param);
|
||||
break;
|
||||
case LOS_SCHED_DEADLINE:
|
||||
EDFProcessDefaultSchedParamGet(param);
|
||||
break;
|
||||
case LOS_SCHED_IDLE:
|
||||
default:
|
||||
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)
|
||||
{
|
||||
LosTaskCB *newTask = HPFRunqueueTopTaskGet(rq->hpfRunqueue);
|
||||
|
||||
if (newTask == NULL) {
|
||||
newTask = rq->idleTask;
|
||||
LosTaskCB *newTask = EDFRunqueueTopTaskGet(rq->edfRunqueue);
|
||||
if (newTask != NULL) {
|
||||
goto FIND;
|
||||
}
|
||||
|
||||
newTask = HPFRunqueueTopTaskGet(rq->hpfRunqueue);
|
||||
if (newTask != NULL) {
|
||||
goto FIND;
|
||||
}
|
||||
|
||||
newTask = rq->idleTask;
|
||||
|
||||
FIND:
|
||||
newTask->ops->start(rq, newTask);
|
||||
return newTask;
|
||||
}
|
||||
|
@ -387,7 +412,7 @@ STATIC VOID SchedTaskSwitch(SchedRunqueue *rq, LosTaskCB *runTask, LosTaskCB *ne
|
|||
OsCpupCycleEndStart(runTask, newTask);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_SCHED_DEBUG
|
||||
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||
UINT64 waitStartTime = newTask->startTime;
|
||||
#endif
|
||||
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);
|
||||
|
||||
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);
|
||||
SchedNextExpireTimeSet(newTask->taskID, deadline, runTask->taskID);
|
||||
|
||||
#ifdef LOSCFG_SCHED_DEBUG
|
||||
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||
newTask->schedStat.waitSchedTime += newTask->startTime - waitStartTime;
|
||||
newTask->schedStat.waitSchedCount++;
|
||||
runTask->schedStat.runTime = runTask->schedStat.allRuntime;
|
||||
|
|
|
@ -99,6 +99,7 @@ UINT32 OsShellShowTickResponse(VOID)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
||||
STATIC VOID SchedDataGet(const LosTaskCB *taskCB, UINT64 *runTime, UINT64 *timeSlice,
|
||||
UINT64 *pendTime, UINT64 *schedWait)
|
||||
{
|
||||
|
@ -128,6 +129,7 @@ UINT32 OsShellShowSchedStatistics(VOID)
|
|||
UINT32 taskLinkNum[LOSCFG_KERNEL_CORE_NUM];
|
||||
UINT32 intSave;
|
||||
LosTaskCB task;
|
||||
SchedEDF *sched = NULL;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
for (UINT16 cpu = 0; cpu < LOSCFG_KERNEL_CORE_NUM; cpu++) {
|
||||
|
@ -150,6 +152,12 @@ UINT32 OsShellShowSchedStatistics(VOID)
|
|||
continue;
|
||||
}
|
||||
|
||||
sched = (SchedEDF *)&taskCB->sp;
|
||||
if (sched->policy == LOS_SCHED_DEADLINE) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
continue;
|
||||
}
|
||||
|
||||
(VOID)memcpy_s(&task, sizeof(LosTaskCB), taskCB, sizeof(LosTaskCB));
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
|
@ -170,3 +178,168 @@ UINT32 OsShellShowSchedStatistics(VOID)
|
|||
}
|
||||
#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_SetProcessPriority(INT32 pid, UINT16 prio);
|
||||
extern INT32 LOS_SetProcessPriority(INT32 pid, INT32 prio);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -514,8 +514,21 @@ typedef struct tagTskInitParam {
|
|||
UINT16 consoleID; /**< The console id of task belongs */
|
||||
UINTPTR processID;
|
||||
UserTaskParam userParam;
|
||||
/* edf parameters */
|
||||
UINT32 runTimeUs;
|
||||
UINT64 deadlineUs;
|
||||
UINT64 periodUs;
|
||||
} TSK_INIT_PARAM_S;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
INT32 priority;
|
||||
INT32 runTimeUs;
|
||||
};
|
||||
INT32 deadlineUs;
|
||||
INT32 periodUs;
|
||||
} LosSchedParam;
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Task name length
|
||||
|
|
|
@ -72,10 +72,10 @@ extern unsigned int SysGetGroupId(void);
|
|||
extern unsigned int SysGetTid(void);
|
||||
extern void SysSchedYield(int type);
|
||||
extern int SysSchedGetScheduler(int id, int flag);
|
||||
extern int SysSchedSetScheduler(int id, int policy, int prio, int flag);
|
||||
extern int SysSchedGetParam(int id, int flag);
|
||||
extern int SysSchedSetParam(int id, unsigned int prio, int flag);
|
||||
extern int SysSetProcessPriority(int which, int who, unsigned int prio);
|
||||
extern int SysSchedSetScheduler(int id, int policy, const LosSchedParam *userParam, int flag);
|
||||
extern int SysSchedGetParam(int id, LosSchedParam *userParam, int flag);
|
||||
extern int SysSchedSetParam(int id, const LosSchedParam *userParam, int flag);
|
||||
extern int SysSetProcessPriority(int which, int who, int prio);
|
||||
extern int SysGetProcessPriority(int which, int who);
|
||||
extern int SysSchedGetPriorityMin(int policy);
|
||||
extern int SysSchedGetPriorityMax(int policy);
|
||||
|
|
|
@ -60,23 +60,44 @@ static int OsPermissionToCheck(unsigned int pid, unsigned int who)
|
|||
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;
|
||||
unsigned int intSave;
|
||||
bool needSched = false;
|
||||
SchedParam param = { 0 };
|
||||
|
||||
if (OS_TID_CHECK_INVALID(tid)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (priority > OS_TASK_PRIORITY_LOWEST) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if ((policy != LOS_SCHED_FIFO) && (policy != LOS_SCHED_RR)) {
|
||||
return EINVAL;
|
||||
ret = UserTaskSchedulerCheck(tid, policy, schedParam, policyFlag);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
param.policy = (policyFlag == true) ? policy : param.policy;
|
||||
param.priority = priority;
|
||||
param.policy = (policyFlag == true) ? (UINT16)policy : param.policy;
|
||||
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);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
|
@ -113,6 +148,7 @@ int SysSchedGetScheduler(int id, int flag)
|
|||
{
|
||||
unsigned int intSave;
|
||||
SchedParam param = { 0 };
|
||||
int policy;
|
||||
int ret;
|
||||
|
||||
if (flag < 0) {
|
||||
|
@ -137,43 +173,57 @@ int SysSchedGetScheduler(int id, int flag)
|
|||
id = (int)LOS_GetCurrProcessID();
|
||||
}
|
||||
|
||||
return LOS_GetProcessScheduler(id);
|
||||
}
|
||||
|
||||
int SysSchedSetScheduler(int id, int policy, int prio, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flag < 0) {
|
||||
return -OsUserTaskSchedulerSet(id, policy, prio, true);
|
||||
ret = LOS_GetProcessScheduler(id, &policy, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
|
||||
return -EINVAL;
|
||||
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;
|
||||
}
|
||||
#else
|
||||
if (param.priority < OS_USER_PROCESS_PRIORITY_HIGHEST) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (id == 0) {
|
||||
id = (int)LOS_GetCurrProcessID();
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
if (prio < OsPidLimitGetPriorityLimit()) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = OsPermissionToCheck(id, LOS_GetCurrProcessID());
|
||||
if (ret < 0) {
|
||||
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 };
|
||||
unsigned int intSave;
|
||||
int ret;
|
||||
|
||||
if (flag < 0) {
|
||||
if (OS_TID_CHECK_INVALID(id)) {
|
||||
|
@ -182,7 +232,7 @@ int SysSchedGetParam(int id, int flag)
|
|||
|
||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(id);
|
||||
SCHEDULER_LOCK(intSave);
|
||||
int ret = OsUserTaskOperatePermissionsCheck(taskCB);
|
||||
ret = OsUserTaskOperatePermissionsCheck(taskCB);
|
||||
if (ret != LOS_OK) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -ret;
|
||||
|
@ -190,25 +240,39 @@ int SysSchedGetParam(int id, int flag)
|
|||
|
||||
taskCB->ops->schedParamGet(taskCB, ¶m);
|
||||
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) {
|
||||
id = (int)LOS_GetCurrProcessID();
|
||||
}
|
||||
|
||||
if (OS_PID_CHECK_INVALID(id)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = LOS_GetProcessScheduler(id, NULL, &schedParam);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0) {
|
||||
id = (int)LOS_GetCurrProcessID();
|
||||
if (LOS_ArchCopyToUser(userParam, &schedParam, sizeof(LosSchedParam))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (OS_PID_CHECK_INVALID(id)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OsGetProcessPriority(LOS_PRIO_PROCESS, id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SysSetProcessPriority(int which, int who, unsigned int prio)
|
||||
int SysSetProcessPriority(int which, int who, int prio)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
|
||||
if (which != LOS_PRIO_PROCESS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -220,6 +284,10 @@ int SysSetProcessPriority(int which, int who, unsigned int prio)
|
|||
if (prio < OsPidLimitGetPriorityLimit()) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#else
|
||||
if (prio < OS_USER_PROCESS_PRIORITY_HIGHEST) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = OsPermissionToCheck(who, LOS_GetCurrProcessID());
|
||||
|
@ -227,22 +295,31 @@ int SysSetProcessPriority(int which, int who, unsigned int prio)
|
|||
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) {
|
||||
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 (prio < OsPidLimitGetPriorityLimit()) {
|
||||
return -EINVAL;
|
||||
if (id == 0) {
|
||||
id = (int)LOS_GetCurrProcessID();
|
||||
}
|
||||
#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)
|
||||
|
|
|
@ -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_getpgid, SysGetProcessGroupID, int, ARG_NUM_1)
|
||||
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_getscheduler, SysSchedGetScheduler, int, ARG_NUM_2)
|
||||
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) {
|
||||
ret = pthread_attr_init(&attr);
|
||||
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_setschedparam(&attr, ¶m);
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include "it_test_process.h"
|
||||
|
||||
|
||||
static const int PROCESS_PRIORITY_MAX = 10;
|
||||
static const int PROCESS_PRIORITY_MIN = 31;
|
||||
static const int PROCESS_SCHED_RR_INTERVAL = 20000000;
|
||||
|
|
|
@ -65,7 +65,7 @@ static int ProcessTest001(void)
|
|||
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
|
||||
|
||||
ret = pthread_attr_init(&a);
|
||||
param.sched_priority += 1;
|
||||
param.sched_priority = 26; /* 26: prio */
|
||||
pthread_attr_setschedparam(&a, ¶m);
|
||||
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
|
||||
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_018.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 = [
|
||||
|
|
|
@ -74,6 +74,14 @@ extern void ItTestPthread016(void);
|
|||
extern void ItTestPthread017(void);
|
||||
extern void ItTestPthread018(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 ItTestPthreadAtfork002(void);
|
||||
extern void ItTestPthreadOnce001(void);
|
||||
|
|
|
@ -186,6 +186,104 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread019, TestSize.Level0)
|
|||
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.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