Commit dbe478cd authored by 吕昶颉's avatar 吕昶颉
Browse files

version:v3

No related merge requests found
Showing with 52 additions and 48 deletions
+52 -48
......@@ -2,14 +2,14 @@
**分支介绍**
- MF-lazy(主分支)
- RMS-lss(未使用懒标记,可进行CR的测试)
- RMS-lss(未使用懒标记)
- Base(课程架构的基础,可进行课程lab的测试)
在课程框架(框架以及完成的任务写在后面)的基础上,尝试实现了RTOS的部分内容,主要有如下内容:
- proc结构体中加入优先级,周期,运行时间等与实时相关的属性
- 实现RMS调度,选择周期最短的进程
- 实现临界资源结构体,并使用Ceiling解决优先级反转的问题(RMS-lss分支中可测试)
- 实现临界资源结构体,并使用Ceiling解决优先级反转的问题
- 实现了多重队列,引入懒标记机制,优化访问次数。
为了简化系统,我们采用了多核独立的方式实现,即每个CPU核独自享有一个调度队列,他们之间只有CR是共享的。
......@@ -85,6 +85,8 @@ typedef struct CR {
2. 在进程切换时,保证让获取CR的进程较为优先,让其尽早完成,释放CR锁,避免频繁切换导致频繁获取释放CR。
在获取和释放时需要将进程放入对应的优先级队列
运行效果:
![CR](./images/CR.png)
......@@ -93,7 +95,6 @@ typedef struct CR {
## 带有懒标记的多重队列
实现位于分支MF-lazy中,引入该方法后还没解决CR部分的错误,所以在MF-lazy中无法进行CR的测试
实现多重队列的动机是减少进程切换时对调度队列的访问次数,但我们发现在RTOS直接使用多重队列其实并没什么用,因为每次切换必须更新current_time,这要求无论如何遍历所有的进程。
......@@ -155,6 +156,9 @@ $$
课程框架中的调度队列是多核共享的,这样实现管理起来比较简洁。但实时任务需要更新current_time,且每个cpu核进行进程切换时都会更新,如果只有一个调度队列,将会导致current_time被多次更新。为了解决这个问题,我们采用多核独立的思路,使用多个调度队列,让每个核独占一个调度队列,以确保时间的正确更新。
4. 使用多重队列获取CR时page fault
之前的版本中CR使用的是睡眠锁,进入睡眠后运行时间应该不会增加,但错误的增加了运行时间,使得进程在睡眠中也能完成,因此会进入complete完成队列,在后续被唤醒时,`activate`会将整个完成队列插入到调度队列中,导致page fault。现在的版本解决了这个问题,使用自旋锁忙等,这样避免了进程命名在等待,却还会认为在执行任务。
# 未来改进方向
......
......@@ -32,71 +32,71 @@ unsigned long random_in_range(unsigned long min, unsigned long max) {
return min + (next_random() % (max - min + 1));
}
static void RT_test_print(u64 a){
u64 i =0;
while(1){
volatile int b = 2;
volatile int c=a+b;
a= b-c;
i++;
if(thread_count<5)
i=0;
if(i>=a*100+123&&thread_count>=NUM_PROCS){
sleep(10);
i=0;
acquire_sched_lock();
sched(RUNNABLE);
}
}
}
// static void RT_test_priority(u64 a){
// static void RT_test_print(u64 a){
// u64 i =0;
// //static CR *cr_list[PROC_CR_COUNT];
// //random_cr_select(cr_list);
// while(1){
// volatile int b = 2;
// volatile int c=a+b;
// a= b-c;
// i++;
// if(i>=a*100+123&&thread_count>=20){
// if(thread_count<5)
// i=0;
// u64 id =random_in_range(0,20);
// if (acquire_CR(id)) {
// printk("cpu %lld Successfully acquired CR lock %lld \n",cpuid(),id);
// }
// // else {
// // printk("process has too many CR lock \n");
// // }
// sleep(11);
// if(i>=a*100+123&&thread_count>=NUM_PROCS){
// sleep(10);
// i=0;
// acquire_sched_lock();
// sched(RUNNABLE);
// }
// }
// }
static void RT_test_priority(u64 a){
u64 i =0;
//static CR *cr_list[PROC_CR_COUNT];
//random_cr_select(cr_list);
while(1){
volatile int b = 2;
volatile int c=a+b;
a= b-c;
i++;
if(i>=a*100+123&&thread_count>=20){
i=0;
u64 id =random_in_range(0,20);
if (acquire_CR(id)) {
printk("cpu %lld Successfully acquired CR lock %lld \n",cpuid(),id);
}
// else {
// printk("process has too many CR lock \n");
// }
sleep(11);
acquire_sched_lock();
sched(RUNNABLE);
}
}
}
void rbtree_test()
{
printk("RTOS_test\n");
init_cr_resources();
//抢占的测试
for(int cid =0;cid<NCPU;cid++)
for (int i = 0; i < NUM_PROCS; i++) {
auto p = RT_create((i+1)*90,10*(i+1));
set_parent_to_this(p);
start_proc_with_id(p, RT_test_print, i,cid);
thread_count++;
}
init_seed(42);
//优先级测试(MQ with Lazy的版本中,还未支持)
// for (int cid =0 ;cid<2;cid++){
// for(int i =0;i<10;i++){
// auto p = RT_create((i+1)*100,10*(i+1));
// for(int cid =0;cid<NCPU;cid++)
// for (int i = 0; i < NUM_PROCS; i++) {
// auto p = RT_create((i+1)*90,10*(i+1));
// set_parent_to_this(p);
// start_proc_with_id(p, RT_test_priority, i,cid);
// start_proc_with_id(p, RT_test_print, i,cid);
// thread_count++;
// }
// }
init_seed(42);
//优先级测试(MQ with Lazy的版本中,还未支持)
for (int cid =0 ;cid<NCPU;cid++){
for(int i =0;i<10;i++){
auto p = RT_create((i+1)*100,10*(i+1));
set_parent_to_this(p);
start_proc_with_id(p, RT_test_priority, i,cid);
thread_count++;
}
}
while(1){
acquire_sched_lock();
sched(RUNNABLE);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment