update lab1-8 codes and docs. now version is 0.2
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#include <vmm.h>
|
||||
#include <proc.h>
|
||||
#include <kdebug.h>
|
||||
#include <monitor.h>
|
||||
#include <kmonitor.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define STACKFRAME_DEPTH 20
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string.h>
|
||||
#include <mmu.h>
|
||||
#include <trap.h>
|
||||
#include <monitor.h>
|
||||
#include <kmonitor.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
/* *
|
||||
@@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
|
||||
/***** Implementations of basic kernel monitor commands *****/
|
||||
|
||||
void
|
||||
monitor(struct trapframe *tf) {
|
||||
kmonitor(struct trapframe *tf) {
|
||||
cprintf("Welcome to the kernel debug monitor!!\n");
|
||||
cprintf("Type 'help' for a list of commands.\n");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <trap.h>
|
||||
|
||||
void monitor(struct trapframe *tf);
|
||||
void kmonitor(struct trapframe *tf);
|
||||
|
||||
int mon_help(int argc, char **argv, struct trapframe *tf);
|
||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <defs.h>
|
||||
#include <stdio.h>
|
||||
#include <intr.h>
|
||||
#include <monitor.h>
|
||||
#include <kmonitor.h>
|
||||
|
||||
static bool is_panic = 0;
|
||||
|
||||
@@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
|
||||
panic_dead:
|
||||
intr_disable();
|
||||
while (1) {
|
||||
monitor(NULL);
|
||||
kmonitor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
0
code/lab8/kern/fs/devs/dev.c
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev.c
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev.h
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev.h
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev_disk0.c
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev_disk0.c
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev_stdin.c
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev_stdin.c
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev_stdout.c
Normal file → Executable file
0
code/lab8/kern/fs/devs/dev_stdout.c
Normal file → Executable file
0
code/lab8/kern/fs/file.c
Normal file → Executable file
0
code/lab8/kern/fs/file.c
Normal file → Executable file
0
code/lab8/kern/fs/file.h
Normal file → Executable file
0
code/lab8/kern/fs/file.h
Normal file → Executable file
2
code/lab8/kern/fs/fs.c
Normal file → Executable file
2
code/lab8/kern/fs/fs.c
Normal file → Executable file
@@ -78,7 +78,7 @@ files_closeall(struct files_struct *filesp) {
|
||||
}
|
||||
|
||||
int
|
||||
dup_fs(struct files_struct *to, struct files_struct *from) {
|
||||
dup_files(struct files_struct *to, struct files_struct *from) {
|
||||
// cprintf("[dup_fs]\n");
|
||||
assert(to != NULL && from != NULL);
|
||||
assert(files_count(to) == 0 && files_count(from) > 0);
|
||||
|
||||
0
code/lab8/kern/fs/fs.h
Normal file → Executable file
0
code/lab8/kern/fs/fs.h
Normal file → Executable file
0
code/lab8/kern/fs/iobuf.c
Normal file → Executable file
0
code/lab8/kern/fs/iobuf.c
Normal file → Executable file
0
code/lab8/kern/fs/iobuf.h
Normal file → Executable file
0
code/lab8/kern/fs/iobuf.h
Normal file → Executable file
0
code/lab8/kern/fs/sfs/bitmap.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/bitmap.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/bitmap.h
Normal file → Executable file
0
code/lab8/kern/fs/sfs/bitmap.h
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs.h
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs.h
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs_fs.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs_fs.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs_inode.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs_inode.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs_io.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs_io.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs_lock.c
Normal file → Executable file
0
code/lab8/kern/fs/sfs/sfs_lock.c
Normal file → Executable file
0
code/lab8/kern/fs/swap/swapfs.c
Normal file → Executable file
0
code/lab8/kern/fs/swap/swapfs.c
Normal file → Executable file
0
code/lab8/kern/fs/swap/swapfs.h
Normal file → Executable file
0
code/lab8/kern/fs/swap/swapfs.h
Normal file → Executable file
0
code/lab8/kern/fs/sysfile.c
Normal file → Executable file
0
code/lab8/kern/fs/sysfile.c
Normal file → Executable file
0
code/lab8/kern/fs/sysfile.h
Normal file → Executable file
0
code/lab8/kern/fs/sysfile.h
Normal file → Executable file
0
code/lab8/kern/fs/vfs/inode.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/inode.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/inode.h
Normal file → Executable file
0
code/lab8/kern/fs/vfs/inode.h
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfs.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfs.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfs.h
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfs.h
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfsdev.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfsdev.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfsfile.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfsfile.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfslookup.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfslookup.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfspath.c
Normal file → Executable file
0
code/lab8/kern/fs/vfs/vfspath.c
Normal file → Executable file
@@ -13,9 +13,10 @@
|
||||
#include <swap.h>
|
||||
#include <proc.h>
|
||||
#include <fs.h>
|
||||
#include <kmonitor.h>
|
||||
|
||||
int kern_init(void) __attribute__((noreturn));
|
||||
|
||||
void grade_backtrace(void);
|
||||
static void lab1_switch_test(void);
|
||||
|
||||
int
|
||||
|
||||
@@ -487,7 +487,7 @@ check_slab(void) {
|
||||
void *v0, *v1;
|
||||
|
||||
size_t nr_free_pages_store = nr_free_pages();
|
||||
size_t slab_allocated_store = slab_allocated();
|
||||
size_t kernel_allocated_store = slab_allocated();
|
||||
|
||||
/* slab must be empty now */
|
||||
check_slab_empty();
|
||||
@@ -633,7 +633,7 @@ check_pass:
|
||||
check_slab_empty();
|
||||
assert(slab_allocated() == 0);
|
||||
assert(nr_free_pages_store == nr_free_pages());
|
||||
assert(slab_allocated_store == slab_allocated());
|
||||
assert(kernel_allocated_store == slab_allocated());
|
||||
|
||||
cprintf("check_slab() succeeded!\n");
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ check_swap(void)
|
||||
list_entry_t *le = &free_list;
|
||||
while ((le = list_next(le)) != &free_list) {
|
||||
struct Page *p = le2page(le, page_link);
|
||||
//assert(PageProperty(p));
|
||||
assert(PageProperty(p));
|
||||
count ++, total += p->property;
|
||||
}
|
||||
assert(total == nr_free_pages());
|
||||
@@ -277,7 +277,7 @@ check_swap(void)
|
||||
struct Page *p = le2page(le, page_link);
|
||||
count --, total -= p->property;
|
||||
}
|
||||
cprintf("count is %d, total is %d\n",count,total);
|
||||
cprintf("count is %d, total is %d\n",count,total);
|
||||
//assert(count == 0);
|
||||
|
||||
cprintf("check_swap() succeeded!\n");
|
||||
|
||||
@@ -460,6 +460,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
|
||||
* page_insert : build the map of phy addr of an Page with the linear addr la
|
||||
* swap_map_swappable : set the page swappable
|
||||
*/
|
||||
/*
|
||||
* LAB5 CHALLENGE ( the implmentation Copy on Write)
|
||||
There are 2 situlations when code comes here.
|
||||
1) *ptep & PTE_P == 1, it means one process try to write a readonly page.
|
||||
If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep.
|
||||
This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method).
|
||||
2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a swap entry.
|
||||
We should add the LAB3's results here.
|
||||
*/
|
||||
if(swap_init_ok) {
|
||||
struct Page *page=NULL;
|
||||
//(1)According to the mm AND addr, try to load the content of right disk page
|
||||
|
||||
@@ -106,6 +106,22 @@ alloc_proc(void) {
|
||||
* uint32_t flags; // Process flag
|
||||
* char name[PROC_NAME_LEN + 1]; // Process name
|
||||
*/
|
||||
//LAB5 YOUR CODE : (update LAB4 steps)
|
||||
/*
|
||||
* below fields(add in LAB5) in proc_struct need to be initialized
|
||||
* uint32_t wait_state; // waiting state
|
||||
* struct proc_struct *cptr, *yptr, *optr; // relations between processes
|
||||
*/
|
||||
//LAB6 YOUR CODE : (update LAB5 steps)
|
||||
/*
|
||||
* below fields(add in LAB6) in proc_struct need to be initialized
|
||||
* struct run_queue *rq; // running queue contains Process
|
||||
* list_entry_t run_link; // the entry linked in run queue
|
||||
* int time_slice; // time slice for occupying the CPU
|
||||
* skew_heap_entry_t lab6_run_pool; // FOR LAB6 ONLY: the entry in the run pool
|
||||
* uint32_t lab6_stride; // FOR LAB6 ONLY: the current stride of the process
|
||||
* uint32_t lab6_priority; // FOR LAB6 ONLY: the priority of process, set by lab6_set_priority(uint32_t)
|
||||
*/
|
||||
//LAB8:EXERCISE2 YOUR CODE HINT:need add some code to init fs in proc_struct, ...
|
||||
}
|
||||
return proc;
|
||||
@@ -355,9 +371,10 @@ copy_thread(struct proc_struct *proc, uintptr_t esp, struct trapframe *tf) {
|
||||
proc->context.esp = (uintptr_t)(proc->tf);
|
||||
}
|
||||
|
||||
//copy_fs&put_fs function used by do_fork in LAB8
|
||||
//copy_files&put_files function used by do_fork in LAB8
|
||||
//copy the files_struct from current to proc
|
||||
static int
|
||||
copy_fs(uint32_t clone_flags, struct proc_struct *proc) {
|
||||
copy_files(uint32_t clone_flags, struct proc_struct *proc) {
|
||||
struct files_struct *filesp, *old_filesp = current->filesp;
|
||||
assert(old_filesp != NULL);
|
||||
|
||||
@@ -371,7 +388,7 @@ copy_fs(uint32_t clone_flags, struct proc_struct *proc) {
|
||||
goto bad_files_struct;
|
||||
}
|
||||
|
||||
if ((ret = dup_fs(filesp, old_filesp)) != 0) {
|
||||
if ((ret = dup_files(filesp, old_filesp)) != 0) {
|
||||
goto bad_dup_cleanup_fs;
|
||||
}
|
||||
|
||||
@@ -386,8 +403,9 @@ bad_files_struct:
|
||||
return ret;
|
||||
}
|
||||
|
||||
//decrease the ref_count of files, and if ref_count==0, then destroy files_struct
|
||||
static void
|
||||
put_fs(struct proc_struct *proc) {
|
||||
put_files(struct proc_struct *proc) {
|
||||
struct files_struct *filesp = proc->filesp;
|
||||
if (filesp != NULL) {
|
||||
if (files_count_dec(filesp) == 0) {
|
||||
@@ -435,6 +453,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
|
||||
// 5. insert proc_struct into hash_list && proc_list
|
||||
// 6. call wakup_proc to make the new child process RUNNABLE
|
||||
// 7. set ret vaule using child proc's pid
|
||||
|
||||
//LAB5 YOUR CODE : (update LAB4 steps)
|
||||
/* Some Functions
|
||||
* set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process
|
||||
* -------------------
|
||||
* update step 1: set child proc's parent to current process, make sure current process's wait_state is 0
|
||||
* update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process
|
||||
*/
|
||||
|
||||
fork_out:
|
||||
return ret;
|
||||
|
||||
@@ -470,7 +497,7 @@ do_exit(int error_code) {
|
||||
}
|
||||
current->mm = NULL;
|
||||
}
|
||||
put_fs(current); //for LAB8
|
||||
put_files(current); //for LAB8
|
||||
current->state = PROC_ZOMBIE;
|
||||
current->exit_code = error_code;
|
||||
|
||||
@@ -787,7 +814,7 @@ init_main(void *arg) {
|
||||
}
|
||||
|
||||
size_t nr_free_pages_store = nr_free_pages();
|
||||
size_t slab_allocated_store = kallocated();
|
||||
size_t kernel_allocated_store = kallocated();
|
||||
|
||||
int pid = kernel_thread(user_main, NULL, 0);
|
||||
if (pid <= 0) {
|
||||
@@ -808,7 +835,7 @@ init_main(void *arg) {
|
||||
assert(list_next(&proc_list) == &(initproc->list_link));
|
||||
assert(list_prev(&proc_list) == &(initproc->list_link));
|
||||
assert(nr_free_pages_store == nr_free_pages());
|
||||
assert(slab_allocated_store == kallocated());
|
||||
assert(kernel_allocated_store == kallocated());
|
||||
cprintf("init check memory pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <assert.h>
|
||||
#include <default_sched.h>
|
||||
|
||||
// the list of timer
|
||||
static list_entry_t timer_list;
|
||||
|
||||
static struct sched_class *sched_class;
|
||||
@@ -48,7 +49,7 @@ sched_init(void) {
|
||||
sched_class = &default_sched_class;
|
||||
|
||||
rq = &__rq;
|
||||
rq->max_time_slice = 20;
|
||||
rq->max_time_slice = MAX_TIME_SLICE;
|
||||
sched_class->init(rq);
|
||||
|
||||
cprintf("sched class: %s\n", sched_class->name);
|
||||
@@ -120,6 +121,7 @@ add_timer(timer_t *timer) {
|
||||
local_intr_restore(intr_flag);
|
||||
}
|
||||
|
||||
// del timer from timer_list
|
||||
void
|
||||
del_timer(timer_t *timer) {
|
||||
bool intr_flag;
|
||||
@@ -139,6 +141,7 @@ del_timer(timer_t *timer) {
|
||||
local_intr_restore(intr_flag);
|
||||
}
|
||||
|
||||
// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
|
||||
void
|
||||
run_timer_list(void) {
|
||||
bool intr_flag;
|
||||
|
||||
@@ -5,17 +5,20 @@
|
||||
#include <list.h>
|
||||
#include <skew_heap.h>
|
||||
|
||||
#define MAX_TIME_SLICE 20
|
||||
|
||||
struct proc_struct;
|
||||
|
||||
typedef struct {
|
||||
unsigned int expires;
|
||||
struct proc_struct *proc;
|
||||
list_entry_t timer_link;
|
||||
unsigned int expires; //the expire time
|
||||
struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled
|
||||
list_entry_t timer_link; //the timer list
|
||||
} timer_t;
|
||||
|
||||
#define le2timer(le, member) \
|
||||
to_struct((le), timer_t, member)
|
||||
|
||||
// init a timer
|
||||
static inline timer_t *
|
||||
timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
|
||||
timer->expires = expires;
|
||||
@@ -62,9 +65,9 @@ struct run_queue {
|
||||
void sched_init(void);
|
||||
void wakeup_proc(struct proc_struct *proc);
|
||||
void schedule(void);
|
||||
void add_timer(timer_t *timer);
|
||||
void del_timer(timer_t *timer);
|
||||
void run_timer_list(void);
|
||||
void add_timer(timer_t *timer); // add timer to timer_list
|
||||
void del_timer(timer_t *timer); // del timer from timer_list
|
||||
void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
|
||||
|
||||
#endif /* !__KERN_SCHEDULE_SCHED_H__ */
|
||||
|
||||
|
||||
@@ -68,11 +68,11 @@ sys_pgdir(uint32_t arg[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
static int
|
||||
sys_gettime(uint32_t arg[]) {
|
||||
return (int)ticks;
|
||||
}
|
||||
static uint32_t
|
||||
static int
|
||||
sys_lab6_set_priority(uint32_t arg[])
|
||||
{
|
||||
uint32_t priority = (uint32_t)arg[0];
|
||||
|
||||
@@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) {
|
||||
break;
|
||||
case IRQ_OFFSET + IRQ_TIMER:
|
||||
#if 0
|
||||
LAB3 : If some page replacement algorithm need tick to change the priority of pages,
|
||||
LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
|
||||
then you can add code here.
|
||||
#endif
|
||||
/* LAB1 YOUR CODE : STEP 3 */
|
||||
@@ -224,15 +224,23 @@ trap_dispatch(struct trapframe *tf) {
|
||||
/* you should upate you lab1 code (just add ONE or TWO lines of code):
|
||||
* Every TICK_NUM cycle, you should set current process's current->need_resched = 1
|
||||
*/
|
||||
|
||||
/* LAB6 YOUR CODE */
|
||||
/* IMPORTANT FUNCTIONS:
|
||||
* run_timer_list
|
||||
*----------------------
|
||||
* you should update your lab5 code (just add ONE or TWO lines of code):
|
||||
* Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler.
|
||||
* You can use one funcitons to finish all these things.
|
||||
*/
|
||||
break;
|
||||
case IRQ_OFFSET + IRQ_COM1:
|
||||
c = cons_getc();
|
||||
cprintf("serial [%03d] %c\n", c, c);
|
||||
break;
|
||||
case IRQ_OFFSET + IRQ_KBD:
|
||||
// There are user level shell in LAB8, so we need change COM/KBD interrupt processing.
|
||||
c = cons_getc();
|
||||
cprintf("kbd [%03d] %c\n", c, c);
|
||||
{
|
||||
extern void dev_stdin_write(char c);
|
||||
dev_stdin_write(c);
|
||||
}
|
||||
break;
|
||||
//LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
|
||||
case T_SWITCH_TOU:
|
||||
|
||||
0
code/lab8/libs/dirent.h
Normal file → Executable file
0
code/lab8/libs/dirent.h
Normal file → Executable file
@@ -3,7 +3,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#define DEPTH 4
|
||||
|
||||
#define SLEEP_TIME 400
|
||||
void forktree(const char *cur);
|
||||
|
||||
void
|
||||
@@ -31,6 +31,8 @@ forktree(const char *cur) {
|
||||
|
||||
int
|
||||
main(void) {
|
||||
cprintf("forktree process will sleep %d ticks\n",SLEEP_TIME);
|
||||
sleep(SLEEP_TIME);
|
||||
forktree("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ sys_sleep(unsigned int time) {
|
||||
return syscall(SYS_sleep, time);
|
||||
}
|
||||
|
||||
size_t
|
||||
int
|
||||
sys_gettime(void) {
|
||||
return syscall(SYS_gettime);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ int sys_getpid(void);
|
||||
int sys_putc(int c);
|
||||
int sys_pgdir(void);
|
||||
int sys_sleep(unsigned int time);
|
||||
size_t sys_gettime(void);
|
||||
int sys_gettime(void);
|
||||
|
||||
struct stat;
|
||||
struct dirent;
|
||||
|
||||
0
code/lab8/user/ls.c
Normal file → Executable file
0
code/lab8/user/ls.c
Normal file → Executable file
0
code/lab8/user/sh.c
Normal file → Executable file
0
code/lab8/user/sh.c
Normal file → Executable file
Reference in New Issue
Block a user