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