6 Commity

Autor SHA1 Wiadomość Data
  423A35C7 faec34e7e9 README添加实验六和实验七 6 miesięcy temu
  423A35C7 f3c2d8b154 实验6 第二版 6 miesięcy temu
  423A35C7 cd00bb2f50 完成实验7 6 miesięcy temu
  423A35C7 714d514a42 实验7环境初始化 6 miesięcy temu
  423A35C7 5e2775f9da 实验6 第一版 6 miesięcy temu
  423A35C7 de32302bd6 实验6环境初始化 6 miesięcy temu
15 zmienionych plików z 221 dodań i 8 usunięć
  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. BIN
      assets/实验七演示.gif
  6. BIN
      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 Wyświetl plik

@ -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 Wyświetl plik

@ -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 Wyświetl plik

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

+ 23
- 1
README.md Wyświetl plik

@ -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时写者需要等待,当有写者在写时其他进程需要等待。在主进程中随机创建读者进程和写者进程,并随机延迟,这样就能体现出读者和写者在不同情况下的互斥与同步是否正确。

BIN
assets/实验七演示.gif Wyświetl plik

Przed Po
Szerokość: 572  |  Wysokość: 805  |  Rozmiar: 1.2 MiB

BIN
assets/实验六演示.gif Wyświetl plik

Przed Po
Szerokość: 572  |  Wysokość: 805  |  Rozmiar: 184 KiB

+ 3
- 0
labcodes_answer/lab6_result/Makefile Wyświetl plik

@ -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 Wyświetl plik

@ -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 Wyświetl plik

@ -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 Wyświetl plik

@ -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 Wyświetl plik

@ -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 Wyświetl plik

@ -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 Wyświetl plik

@ -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 Wyświetl plik

@ -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 Wyświetl plik

@ -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); //
}
}

Ładowanie…
Anuluj
Zapisz