Prechádzať zdrojové kódy

增加进程的调度policy属性 (#63)

* 添加进程的policy属性

* update

* 修改设置进程策略

* 删除重复定义

* 更正注释及格式

Co-authored-by: longjin <[email protected]>
kong 2 rokov pred
rodič
commit
ed178b560b

+ 77 - 77
kernel/process/proc-types.h

@@ -36,29 +36,29 @@
 
 struct thread_struct
 {
-	// 内核层栈基指针
-	ul rbp; // in tss rsp0
-	// 内核层代码指针
-	ul rip;
-	// 内核层栈指针
-	ul rsp;
-
-	ul fs, gs;
-
-	ul cr2;
-	// 异常号
-	ul trap_num;
-	// 错误码
-	ul err_code;
+    // 内核层栈基指针
+    ul rbp; // in tss rsp0
+    // 内核层代码指针
+    ul rip;
+    // 内核层栈指针
+    ul rsp;
+
+    ul fs, gs;
+
+    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;
-
-	// 进程切换时保存的状态信息
-	struct thread_struct *thread;
-
-	// 连接各个pcb的双向链表
-	struct List list;
-
-	// 地址空间范围
-	// 用户空间: 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; // 虚拟运行时间
-
-	// 进程拥有的文件描述符的指针数组
-	// todo: 改用动态指针数组
-	struct vfs_file_t *fds[PROC_MAX_FD_NUM];
-
-	// 链表中的下一个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; // 子进程退出等待队列
-
-	/* PF_kTHREAD  | PF_IO_WORKER 的进程,worker_private不为NULL*/
-	void *worker_private;
+    // 进程的状态
+    volatile long state;
+    // 进程标志:进程、线程、内核线程
+    unsigned long flags;
+    int64_t preempt_count; // 持有的自旋锁的数量
+    long signal;
+    long cpu_id; // 当前进程在哪个CPU核心上运行
+    // 内存空间分布结构体, 记录内存页表和程序段信息
+    struct mm_struct *mm;
+
+    // 进程切换时保存的状态信息
+    struct thread_struct *thread;
+
+    // 连接各个pcb的双向链表
+    struct List list;
+
+    // 地址空间范围
+    // 用户空间: 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; // 虚拟运行时间
+
+    // 进程拥有的文件描述符的指针数组
+    // todo: 改用动态指针数组
+    struct vfs_file_t *fds[PROC_MAX_FD_NUM];
+
+    // 链表中的下一个pcb
+    struct process_control_block *next_pcb;
+    // 父进程的pcb
+    struct process_control_block *parent_pcb;
+
+    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;
 };
 
 // 将进程的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表明是紧凑结构,编译器不会对成员变量进行字节对齐。

+ 3 - 2
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);
 

+ 0 - 1
kernel/sched/cfs.c

@@ -81,7 +81,6 @@ void sched_cfs()
             }
         }
 
-
         process_switch_mm(proc);
 
         switch_proc(current_pcb, proc);

+ 45 - 1
kernel/sched/sched.c

@@ -1,9 +1,53 @@
 #include "sched.h"
 #include <common/kprint.h>
-#include <driver/video/video.h>
 #include <common/spinlock.h>
+#include <driver/video/video.h>
 #include <sched/cfs.h>
 
+/**
+ * @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加入就绪队列
  *

+ 55 - 1
kernel/sched/sched.h

@@ -2,6 +2,61 @@
 
 #include <common/glib.h>
 #include <process/process.h>
+
+/*
+ * 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();
 
 /**