From ed178b560bb1952580768af76f4655d34f38bb58 Mon Sep 17 00:00:00 2001 From: kong <45937622+kkkkkong@users.noreply.github.com> Date: Fri, 21 Oct 2022 20:38:01 +0800 Subject: [PATCH] =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E7=9A=84=E8=B0=83=E5=BA=A6policy=E5=B1=9E=E6=80=A7=20(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加进程的policy属性 * update * 修改设置进程策略 * 删除重复定义 * 更正注释及格式 Co-authored-by: longjin --- kernel/process/proc-types.h | 134 ++++++++++++++++++------------------ kernel/process/process.h | 5 +- kernel/sched/cfs.c | 1 - kernel/sched/sched.c | 46 ++++++++++++- kernel/sched/sched.h | 56 ++++++++++++++- 5 files changed, 170 insertions(+), 72 deletions(-) diff --git a/kernel/process/proc-types.h b/kernel/process/proc-types.h index 284c4a07..6fa634e1 100644 --- a/kernel/process/proc-types.h +++ b/kernel/process/proc-types.h @@ -36,29 +36,29 @@ struct thread_struct { - // 内核层栈基指针 - ul rbp; // in tss rsp0 - // 内核层代码指针 - ul rip; - // 内核层栈指针 - ul rsp; + // 内核层栈基指针 + ul rbp; // in tss rsp0 + // 内核层代码指针 + ul rip; + // 内核层栈指针 + ul rsp; - ul fs, gs; + ul fs, gs; - ul cr2; - // 异常号 - ul trap_num; - // 错误码 - ul err_code; + ul cr2; + // 异常号 + ul trap_num; + // 错误码 + ul err_code; }; // ========= pcb->flags ========= // 进程标志位 -#define PF_KTHREAD (1UL << 0) // 内核线程 +#define PF_KTHREAD (1UL << 0) // 内核线程 #define PF_NEED_SCHED (1UL << 1) // 进程需要被调度 -#define PF_VFORK (1UL << 2) // 标志进程是否由于vfork而存在资源共享 -#define PF_KFORK (1UL << 3) // 标志在内核态下调用fork(临时标记,do_fork()结束后会将其复位) -#define PF_NOFREEZE (1UL << 4) // 当前进程不能被冻结 +#define PF_VFORK (1UL << 2) // 标志进程是否由于vfork而存在资源共享 +#define PF_KFORK (1UL << 3) // 标志在内核态下调用fork(临时标记,do_fork()结束后会将其复位) +#define PF_NOFREEZE (1UL << 4) // 当前进程不能被冻结 /** * @brief 进程控制块 @@ -66,70 +66,70 @@ struct thread_struct */ struct process_control_block { - // 进程的状态 - volatile long state; - // 进程标志:进程、线程、内核线程 - unsigned long flags; - int64_t preempt_count; // 持有的自旋锁的数量 - long signal; - long cpu_id; // 当前进程在哪个CPU核心上运行 - // 内存空间分布结构体, 记录内存页表和程序段信息 - struct mm_struct *mm; + // 进程的状态 + volatile long state; + // 进程标志:进程、线程、内核线程 + unsigned long flags; + int64_t preempt_count; // 持有的自旋锁的数量 + long signal; + long cpu_id; // 当前进程在哪个CPU核心上运行 + // 内存空间分布结构体, 记录内存页表和程序段信息 + struct mm_struct *mm; - // 进程切换时保存的状态信息 - struct thread_struct *thread; + // 进程切换时保存的状态信息 + struct thread_struct *thread; - // 连接各个pcb的双向链表 - struct List list; + // 连接各个pcb的双向链表 + struct List list; - // 地址空间范围 - // 用户空间: 0x0000 0000 0000 0000 ~ 0x0000 7fff ffff ffff - // 内核空间: 0xffff 8000 0000 0000 ~ 0xffff ffff ffff ffff - uint64_t addr_limit; + // 地址空间范围 + // 用户空间: 0x0000 0000 0000 0000 ~ 0x0000 7fff ffff ffff + // 内核空间: 0xffff 8000 0000 0000 ~ 0xffff ffff ffff ffff + uint64_t addr_limit; - long pid; - long priority; // 优先级 - int64_t virtual_runtime; // 虚拟运行时间 + long pid; + long priority; // 优先级 + int64_t virtual_runtime; // 虚拟运行时间 - // 进程拥有的文件描述符的指针数组 - // todo: 改用动态指针数组 - struct vfs_file_t *fds[PROC_MAX_FD_NUM]; + // 进程拥有的文件描述符的指针数组 + // todo: 改用动态指针数组 + struct vfs_file_t *fds[PROC_MAX_FD_NUM]; - // 链表中的下一个pcb - struct process_control_block *next_pcb; - // 父进程的pcb - struct process_control_block *parent_pcb; + // 链表中的下一个pcb + struct process_control_block *next_pcb; + // 父进程的pcb + struct process_control_block *parent_pcb; - int32_t exit_code; // 进程退出时的返回码 - wait_queue_node_t wait_child_proc_exit; // 子进程退出等待队列 + int32_t exit_code; // 进程退出时的返回码 + uint32_t policy; // 进程调度策略标志位 + wait_queue_node_t wait_child_proc_exit; // 子进程退出等待队列 - /* PF_kTHREAD | PF_IO_WORKER 的进程,worker_private不为NULL*/ - void *worker_private; + /* PF_kTHREAD | PF_IO_WORKER 的进程,worker_private不为NULL*/ + void *worker_private; }; // 将进程的pcb和内核栈融合到一起,8字节对齐 -union proc_union -{ - struct process_control_block pcb; - ul stack[STACK_SIZE / sizeof(ul)]; +union proc_union { + struct process_control_block pcb; + ul stack[STACK_SIZE / sizeof(ul)]; } __attribute__((aligned(8))); struct tss_struct { - unsigned int reserved0; - ul rsp0; - ul rsp1; - ul rsp2; - ul reserved1; - ul ist1; - ul ist2; - ul ist3; - ul ist4; - ul ist5; - ul ist6; - ul ist7; - ul reserved2; - unsigned short reserved3; - // io位图基地址 - unsigned short io_map_base_addr; + unsigned int reserved0; + ul rsp0; + ul rsp1; + ul rsp2; + ul reserved1; + ul ist1; + ul ist2; + ul ist3; + ul ist4; + ul ist5; + ul ist6; + ul ist7; + ul reserved2; + unsigned short reserved3; + // io位图基地址 + unsigned short io_map_base_addr; } __attribute__((packed)); // 使用packed表明是紧凑结构,编译器不会对成员变量进行字节对齐。 \ No newline at end of file diff --git a/kernel/process/process.h b/kernel/process/process.h index 9b6a0d16..b289eb99 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -45,7 +45,8 @@ .parent_pcb = &proc, \ .exit_code = 0, \ .wait_child_proc_exit = 0, \ - .worker_private = NULL \ + .worker_private = NULL, \ + .policy = SCHED_NORMAL \ } /** @@ -183,7 +184,7 @@ void process_exit_notify(); * @return int */ -pid_t kernel_thread(int (*fn)(void*), void* arg, unsigned long flags); +pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); int process_fd_alloc(struct vfs_file_t *file); diff --git a/kernel/sched/cfs.c b/kernel/sched/cfs.c index 9319891f..36cd4fd4 100644 --- a/kernel/sched/cfs.c +++ b/kernel/sched/cfs.c @@ -81,7 +81,6 @@ void sched_cfs() } } - process_switch_mm(proc); switch_proc(current_pcb, proc); diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c index 8f3d7b36..3bda538c 100644 --- a/kernel/sched/sched.c +++ b/kernel/sched/sched.c @@ -1,9 +1,53 @@ #include "sched.h" #include -#include #include +#include #include +/** + * @brief + * + * @param p pcb + * @param attr 调度属性 + * @param user 请求是否来自用户态 + * @param pi + * @return int + */ +static int __sched_setscheduler(struct process_control_block *p, const struct sched_attr *attr, bool user, bool pi) +{ + int policy = attr->sched_policy; +recheck:; + // 这里policy的设置小于0是因为,需要在临界区内更新值之后,重新到这里判断 + if (!IS_VALID_SCHED_POLICY(policy)) + { + return -EINVAL; + } + // 修改成功 + p->policy = policy; + return 0; +} + +static int _sched_setscheduler(struct process_control_block *p, int policy, const struct sched_param *param, bool check) +{ + struct sched_attr attr = {.sched_policy = policy}; + + return __sched_setscheduler(p, &attr, check, true); +} + +/** + * sched_setscheduler -设置进程的调度策略 + * @param p 需要修改的pcb + * @param policy 需要设置的policy + * @param param structure containing the new RT priority. 目前没有用 + * + * @return 成功返回0,否则返回对应的错误码 + * + */ +int sched_setscheduler(struct process_control_block *p, int policy, const struct sched_param *param) +{ + return _sched_setscheduler(p, policy, param, true); +} + /** * @brief 包裹shced_cfs_enqueue(),将PCB加入就绪队列 * diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 085050f9..dc4e98a1 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2,6 +2,61 @@ #include #include + +/* + * Scheduling policies + */ +#define SCHED_NORMAL 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 +#define SCHED_BATCH 3 +/* SCHED_ISO: reserved but not implemented yet */ +#define SCHED_IDLE 5 +#define SCHED_DEADLINE 6 +#define SCHED_MAX_POLICY_NUM SCHED_DEADLINE + +#define IS_VALID_SCHED_POLICY(_policy) ((_policy) > 0 && (_policy) <= SCHED_MAX_POLICY_NUM) + +struct sched_param +{ + int sched_priority; +}; +struct sched_attr +{ + uint32_t size; + + uint32_t sched_policy; + uint64_t sched_flags; + + /* SCHED_NORMAL, SCHED_BATCH */ + int32_t sched_nice; + + /* SCHED_FIFO, SCHED_RR */ + uint32_t sched_priority; + + /* SCHED_DEADLINE */ + uint64_t sched_runtime; + uint64_t sched_deadline; + uint64_t sched_period; + + /* Utilization hints */ + uint32_t sched_util_min; + uint32_t sched_util_max; +}; + +static int __sched_setscheduler(struct process_control_block *p, const struct sched_attr *attr, bool user, bool pi); +static int _sched_setscheduler(struct process_control_block *p, int policy, const struct sched_param *param, + bool check); +/** + * sched_setscheduler -设置进程的调度策略 + * @param p 需要修改的pcb + * @param policy 需要设置的policy + * @param param structure containing the new RT priority. 目前没有用 + * + * @return 成功返回0,否则返回对应的错误码 + * + */ +int sched_setscheduler(struct process_control_block *p, int policy, const struct sched_param *param); /** * @brief 包裹sched_enqueue(),将PCB加入就绪队列 * @@ -14,7 +69,6 @@ void sched_enqueue(struct process_control_block *pcb); */ void sched(); - void sched_init(); /**