6 コミット

作成者 SHA1 メッセージ 日付
  423A35C7 faec34e7e9 README添加实验六和实验七 5ヶ月前
  423A35C7 f3c2d8b154 实验6 第二版 5ヶ月前
  423A35C7 cd00bb2f50 完成实验7 5ヶ月前
  423A35C7 714d514a42 实验7环境初始化 5ヶ月前
  423A35C7 5e2775f9da 实验6 第一版 5ヶ月前
  423A35C7 de32302bd6 实验6环境初始化 5ヶ月前
15個のファイルの変更221行の追加8行の削除
分割表示
  1. +1
    -1
      .vscode/c_cpp_properties.json
  2. +1
    -1
      .vscode/launch.json
  3. +1
    -1
      .vscode/tasks.json
  4. +23
    -1
      README.md
  5. バイナリ
      assets/实验七演示.gif
  6. バイナリ
      assets/实验六演示.gif
  7. +3
    -0
      labcodes_answer/lab6_result/Makefile
  8. +20
    -0
      labcodes_answer/lab6_result/kern/process/proc.c
  9. +88
    -1
      labcodes_answer/lab6_result/kern/schedule/default_sched.c
  10. +1
    -0
      labcodes_answer/lab6_result/kern/schedule/default_sched.h
  11. +1
    -1
      labcodes_answer/lab6_result/kern/schedule/sched.c
  12. +1
    -0
      labcodes_answer/lab6_result/kern/schedule/sched.h
  13. +3
    -0
      labcodes_answer/lab7_result/Makefile
  14. +2
    -2
      labcodes_answer/lab7_result/kern/process/proc.c
  15. +76
    -0
      labcodes_answer/lab7_result/kern/sync/read_write_sync.c

+ 1
- 1
.vscode/c_cpp_properties.json ファイルの表示

@ -6,7 +6,7 @@
"${workspaceFolder}/**",
// "${workspaceFolder}/labcodes_answer/**/",
// lab1_resultlab2_result
"${workspaceFolder}/labcodes_answer/lab5_result/**/"
"${workspaceFolder}/labcodes_answer/lab7_result/**/"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",

+ 1
- 1
.vscode/launch.json ファイルの表示

@ -11,7 +11,7 @@
"program": "bin/kernel",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/labcodes_answer/lab5_result",
"cwd": "${workspaceFolder}/labcodes_answer/lab7_result",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",

+ 1
- 1
.vscode/tasks.json ファイルの表示

@ -9,7 +9,7 @@
"env": {
"DISPLAY": ":0",
},
"cwd": "${workspaceFolder}/labcodes_answer/lab5_result"
"cwd": "${workspaceFolder}/labcodes_answer/lab7_result"
},
"problemMatcher": [

+ 23
- 1
README.md ファイルの表示

@ -20,4 +20,26 @@
### 效果
![](assets/实验三演示.gif)
### 原理
在swap_fifo.c文件中,修改_fifo_swap_out_victim(或者新建一个函数)。当需要换出页面时,从链表尾部取出一个页面,如果这个页面的访问位是1,那么将其访问位改为0,并放到链表头部。接着再从链表尾部检测下一个页面,直到找到一个访问位为0页面的作为换出的页面。(测试函数_fifo_check_swap也需要略微更改)
在swap_fifo.c文件中,修改_fifo_swap_out_victim(或者新建一个函数)。当需要换出页面时,从链表尾部取出一个页面,如果这个页面的访问位是1,那么将其访问位改为0,并放到链表头部。接着再从链表尾部检测下一个页面,直到找到一个访问位为0页面的作为换出的页面。(测试函数_fifo_check_swap也需要略微更改)
## 实验四
无编程作业。
## 实验五
无编程作业。
## 实验六
### 题目
编程实现理论课中的彩票进程调度算法。(算法的描述以及实现思路可以参考理论课教材和课程PPT)
### 效果
![](assets/实验六演示.gif)
### 原理
在default_sched.c文件中,新建彩票进程调度的几个函数。将进程的优先级作为彩票数量,在入队和出队时维护运行队列中的优先级总和,当需要选择下一个调度的进程时,从0到优先级总和的范围中选取一个随机数,之后把运行队列中进程优先级逐个相加,直到大于此随机数,这说明此随机数在这个进程拥有的彩票范围内。
## 实验七
### 题目
利用信号量机制实现读者写者问题的同步关系。(算法的描述以及实现思路可以参考理论课教材和课程PPT)
### 效果
![](assets/实验七演示.gif)
### 原理
读者和读者不需要互斥,读者和写者需要互斥,写者和写者需要互斥。维护当前读者数量的变量,当大于0时写者需要等待,当有写者在写时其他进程需要等待。在主进程中随机创建读者进程和写者进程,并随机延迟,这样就能体现出读者和写者在不同情况下的互斥与同步是否正确。

バイナリ
assets/实验七演示.gif ファイルの表示

変更前 変更後
幅: 572  |  高さ: 805  |  サイズ: 1.2 MiB

バイナリ
assets/实验六演示.gif ファイルの表示

変更前 変更後
幅: 572  |  高さ: 805  |  サイズ: 184 KiB

+ 3
- 0
labcodes_answer/lab6_result/Makefile ファイルの表示

@ -253,6 +253,7 @@ endif
# files for grade script
TARGETS: $(TARGETS)
all: $(TARGETS)
.DEFAULT_GOAL := TARGETS
@ -268,6 +269,8 @@ qemu-nox: $(UCOREIMG) $(SWAPIMG)
$(V)$(QEMU) -serial mon:stdio $(QEMUOPTS) -nographic
TERMINAL := gnome-terminal
gdb: $(UCOREIMG) $(SWAPIMG)
$(V)$(QEMU) -S -s -parallel stdio $(QEMUOPTS) -serial null
debug: $(UCOREIMG) $(SWAPIMG)
$(V)$(QEMU) -S -s -parallel stdio $(QEMUOPTS) -serial null &

+ 20
- 0
labcodes_answer/lab6_result/kern/process/proc.c ファイルの表示

@ -820,9 +820,19 @@ user_main(void *arg) {
panic("user_main execve failed.\n");
}
static int
my_test_user_main(void *arg) {
int num = (int)arg;
int priority = (rand() % 100) * 100;
cprintf("process %d, priority %d\n", num, priority);
lab6_set_priority(priority);
cprintf("process %d end\n", num);
}
// init_main - the second kernel thread used to create user_main kernel threads
static int
init_main(void *arg) {
srand((unsigned int)0);
size_t nr_free_pages_store = nr_free_pages();
size_t kernel_allocated_store = kallocated();
@ -831,6 +841,16 @@ init_main(void *arg) {
panic("create user_main failed.\n");
}
// error: for loop initial declarations are only allowed in C99 mode
int i = 0;
for (; i < 10; i++) {
int pid = kernel_thread(my_test_user_main, (void *)i, 0);
if (pid <= 0) {
panic("create my_test_user_main failed.\n");
}
struct proc_strucht *proc = find_proc(pid);
}
while (do_wait(0, NULL) == 0) {
schedule();
}

+ 88
- 1
labcodes_answer/lab6_result/kern/schedule/default_sched.c ファイルの表示

@ -2,9 +2,10 @@
#include <list.h>
#include <proc.h>
#include <assert.h>
// #include <time.h> //
#include <default_sched.h>
#define USE_SKEW_HEAP 1
#define USE_SKEW_HEAP 0
/* You should define the BigStride constant here*/
/* LAB6: YOUR CODE */
@ -152,6 +153,84 @@ stride_proc_tick(struct run_queue *rq, struct proc_struct *proc) {
}
}
static void
ticket_init(struct run_queue *rq) {
list_init(&(rq->run_list));
rq->lab6_run_pool = NULL;
rq->proc_num = 0;
}
static void
ticket_enqueue(struct run_queue *rq, struct proc_struct *proc) {
/* LAB6: YOUR CODE */
#if USE_SKEW_HEAP
rq->lab6_run_pool =
skew_heap_insert(rq->lab6_run_pool, &(proc->lab6_run_pool), proc_stride_comp_f);
#else
assert(list_empty(&(proc->run_link)));
list_add_before(&(rq->run_list), &(proc->run_link));
#endif
if (proc->time_slice == 0 || proc->time_slice > rq->max_time_slice) {
proc->time_slice = rq->max_time_slice;
}
proc->rq = rq;
rq->proc_num ++;
rq->lab6_total_num += proc->lab6_priority + 1;
}
static struct proc_struct *
ticket_pick_next(struct run_queue *rq) {
/* LAB6: YOUR CODE */
uint32_t target_index = rand() % rq->lab6_total_num;
#if USE_SKEW_HEAP
if (rq->lab6_run_pool == NULL) return NULL;
struct proc_struct *p = le2proc(rq->lab6_run_pool, lab6_run_pool);
#else
list_entry_t *le = list_next(&(rq->run_list));
if (le == &rq->run_list)
return NULL;
struct proc_struct *p;
int32_t temp_ticket_sum = 0;
while (le != &rq->run_list)
{
p = le2proc(le, run_link);
temp_ticket_sum += p->lab6_priority + 1;
if (temp_ticket_sum >= target_index)
break;
le = list_next(le);
}
#endif
return p;
}
static void
ticket_dequeue(struct run_queue *rq, struct proc_struct *proc) {
/* LAB6: YOUR CODE */
#if USE_SKEW_HEAP
rq->lab6_run_pool =
skew_heap_remove(rq->lab6_run_pool, &(proc->lab6_run_pool), proc_stride_comp_f);
#else
assert(!list_empty(&(proc->run_link)) && proc->rq == rq);
list_del_init(&(proc->run_link));
#endif
rq->proc_num --;
rq->lab6_total_num -= proc->lab6_priority + 1;
}
static void
ticket_proc_tick(struct run_queue *rq, struct proc_struct *proc) {
/* LAB6: YOUR CODE */
if (proc->time_slice > 0) {
proc->time_slice --;
}
if (proc->time_slice == 0) {
proc->need_resched = 1;
}
}
struct sched_class default_sched_class = {
.name = "stride_scheduler",
.init = stride_init,
@ -161,3 +240,11 @@ struct sched_class default_sched_class = {
.proc_tick = stride_proc_tick,
};
struct sched_class ticket_sched_class = {
.name = "ticket_scheduler",
.init = ticket_init,
.enqueue = ticket_enqueue,
.dequeue = ticket_dequeue,
.pick_next = ticket_pick_next,
.proc_tick = ticket_proc_tick,
};

+ 1
- 0
labcodes_answer/lab6_result/kern/schedule/default_sched.h ファイルの表示

@ -4,6 +4,7 @@
#include <sched.h>
extern struct sched_class default_sched_class;
extern struct sched_class ticket_sched_class;
#endif /* !__KERN_SCHEDULE_SCHED_RR_H__ */

+ 1
- 1
labcodes_answer/lab6_result/kern/schedule/sched.c ファイルの表示

@ -46,7 +46,7 @@ void
sched_init(void) {
list_init(&timer_list);
sched_class = &default_sched_class;
sched_class = &ticket_sched_class;
rq = &__rq;
rq->max_time_slice = MAX_TIME_SLICE;

+ 1
- 0
labcodes_answer/lab6_result/kern/schedule/sched.h ファイルの表示

@ -42,6 +42,7 @@ struct run_queue {
int max_time_slice;
// For LAB6 ONLY
skew_heap_entry_t *lab6_run_pool;
uint32_t lab6_total_num;
};
void sched_init(void);

+ 3
- 0
labcodes_answer/lab7_result/Makefile ファイルの表示

@ -253,6 +253,7 @@ endif
# files for grade script
TARGETS: $(TARGETS)
all: $(TARGETS)
.DEFAULT_GOAL := TARGETS
@ -268,6 +269,8 @@ qemu-nox: $(UCOREIMG) $(SWAPIMG)
$(V)$(QEMU) -serial mon:stdio $(QEMUOPTS) -nographic
TERMINAL := gnome-terminal
gdb: $(UCOREIMG) $(SWAPIMG)
$(V)$(QEMU) -S -s -parallel stdio $(QEMUOPTS) -serial null
debug: $(UCOREIMG) $(SWAPIMG)
$(V)$(QEMU) -S -s -parallel stdio $(QEMUOPTS) -serial null &

+ 2
- 2
labcodes_answer/lab7_result/kern/process/proc.c ファイルの表示

@ -844,8 +844,8 @@ init_main(void *arg) {
if (pid <= 0) {
panic("create user_main failed.\n");
}
extern void check_sync(void);
check_sync(); // check philosopher sync problem
extern void read_write_sync(void);
read_write_sync(); // check philosopher sync problem
while (do_wait(0, NULL) == 0) {
schedule();

+ 76
- 0
labcodes_answer/lab7_result/kern/sync/read_write_sync.c ファイルの表示

@ -0,0 +1,76 @@
#include <stdio.h>
#include <proc.h>
#include <sem.h>
#include <monitor.h>
#include <assert.h>
#define READER_NUM 100 // 读者数量,取值应大于1,小于int范围
#define WRITER_NUM 100 // 写者数量,取值应大于1,小于int范围
// #define BUFFER_NUM 10 // 1int范围
#define SLEEP_TIME 10
// down和upP和V acquire和release吧
#define acquire down
#define release up
semaphore_t mutex; /* 临界区互斥 */
semaphore_t synchronization; //
int read_pos_write_neg = 0; //
int buffer;
int reader(int index){
lab6_set_priority(rand() % 100);
int result;
acquire(&mutex);
read_pos_write_neg++;
if (read_pos_write_neg == 1)
acquire(&synchronization);
release(&mutex);
do_sleep(rand() % SLEEP_TIME); //
result = buffer;
acquire(&mutex);
read_pos_write_neg--;
assert(read_pos_write_neg >=0);
if (read_pos_write_neg == 0) {
release(&synchronization);
}
release(&mutex);
cprintf("reader %2d read %2d\n", index, result);
return result;
}
void writer(int index) {
lab6_set_priority(rand() % 100);
int write_data = rand() % 100;
acquire(&synchronization);
do_sleep(rand() % SLEEP_TIME); //
buffer = write_data;
release(&synchronization);
cprintf("writer %2d writed %2d\n", index, write_data);
}
void read_write_sync() {
sem_init(&mutex, 1);
sem_init(&synchronization, 1);
int reader_num = 0, writer_num = 0;
while (reader_num < READER_NUM || writer_num < WRITER_NUM) {
if (rand() % 2) {
if (reader_num < READER_NUM) {
int pid = kernel_thread(reader, (void *)reader_num, 0);
if (pid <= 0) {
panic("create No.%d reader failed.\n");
}
reader_num++;
}
} else {
if (writer_num < WRITER_NUM) {
int pid = kernel_thread(writer, (void *)writer_num, 0);
if (pid <= 0) {
panic("create No.%d writer failed.\n");
}
writer_num++;
}
}
do_sleep(rand() % SLEEP_TIME); //
}
}

読み込み中…
キャンセル
保存