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:
zhangdengyu
2023-04-08 22:47:03 +08:00
parent 4ff66c7f40
commit 13f68dcf9c
33 changed files with 2054 additions and 161 deletions

View File

@@ -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);

View File

@@ -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, &param);
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, &param);
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(&param, userParam, sizeof(LosSchedParam)) != 0) {
return -EFAULT;
}
if (flag < 0) {
return -OsUserTaskSchedulerSet(id, policy, &param, 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, &param);
}
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, &param);
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(&param, userParam, sizeof(LosSchedParam)) != 0) {
return -EFAULT;
}
return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, &param, 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)

View File

@@ -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)