cow lab initialized
This commit is contained in:
@@ -80,7 +80,6 @@ int pipewrite(struct pipe*, uint64, int);
|
||||
int printf(char*, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void panic(char*) __attribute__((noreturn));
|
||||
void printfinit(void);
|
||||
void backtrace(void);
|
||||
|
||||
// proc.c
|
||||
int cpuid(void);
|
||||
|
||||
@@ -176,24 +176,3 @@ printfinit(void)
|
||||
initlock(&pr.lock, "pr");
|
||||
pr.locking = 1;
|
||||
}
|
||||
|
||||
// 打印当前调用栈的返回地址,实现简单的函数回溯,用于调试。
|
||||
void
|
||||
backtrace(void)
|
||||
{
|
||||
printf("barcktrace:\n");
|
||||
|
||||
uint64 ra,fp = r_fp();//frame pointer -> address
|
||||
uint64 pre_fp = *((uint64*)(fp - 16));
|
||||
|
||||
// 只要当前fp和上一个fp在同一页内,就继续回溯
|
||||
while(PGROUNDDOWN(fp)==PGROUNDDOWN(pre_fp)){
|
||||
ra = *(uint64 *)(fp - 8); // 取出返回地址
|
||||
printf("%p\n", (void*)ra); // 打印返回地址
|
||||
fp = pre_fp; // 更新fp为上一个fp
|
||||
pre_fp = *((uint64*)(fp - 16)); // 获取新的上一个fp
|
||||
}
|
||||
|
||||
ra = *(uint64 *)(fp - 8);
|
||||
printf("%p\n",(void*)ra);
|
||||
}
|
||||
@@ -132,13 +132,6 @@ found:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 为进程分配 pre_trapframe 空间,分配失败则释放进程资源并返回 0
|
||||
if((p->pre_trapframe = (struct trapframe *)kalloc()) == 0){
|
||||
freeproc(p);
|
||||
release(&p->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// An empty user page table.
|
||||
p->pagetable = proc_pagetable(p);
|
||||
if(p->pagetable == 0){
|
||||
@@ -167,10 +160,6 @@ freeproc(struct proc *p)
|
||||
p->trapframe = 0;
|
||||
if(p->pagetable)
|
||||
proc_freepagetable(p->pagetable, p->sz);
|
||||
// 如果进程的 pre_trapframe 存在,则释放其占用的内存,并将指针置为 0,防止悬空指针。
|
||||
if(p->pre_trapframe)
|
||||
kfree((void*)p->pre_trapframe);
|
||||
p->pre_trapframe = 0;
|
||||
p->pagetable = 0;
|
||||
p->sz = 0;
|
||||
p->pid = 0;
|
||||
|
||||
@@ -104,8 +104,4 @@ struct proc {
|
||||
struct file *ofile[NOFILE]; // Open files
|
||||
struct inode *cwd; // Current directory
|
||||
char name[16]; // Process name (debugging)
|
||||
int alarm_cnt; // Alarm count 触发alarm的时钟中断数量
|
||||
int inter_cnt; // interrupts count 需要统计的时钟中断的数量
|
||||
uint64 handler; // alarm func address 记录处理alarm的函数的地址
|
||||
struct trapframe *pre_trapframe;
|
||||
};
|
||||
|
||||
@@ -338,15 +338,6 @@ r_ra()
|
||||
return x;
|
||||
}
|
||||
|
||||
// 读取当前帧指针(s0)寄存器的值
|
||||
static inline uint64
|
||||
r_fp()
|
||||
{
|
||||
uint64 x;
|
||||
asm volatile("mv %0, s0" : "=r" (x) );
|
||||
return x;
|
||||
}
|
||||
|
||||
// flush the TLB.
|
||||
static inline void
|
||||
sfence_vma()
|
||||
|
||||
@@ -101,8 +101,6 @@ extern uint64 sys_unlink(void);
|
||||
extern uint64 sys_link(void);
|
||||
extern uint64 sys_mkdir(void);
|
||||
extern uint64 sys_close(void);
|
||||
extern uint64 sys_sigalarm(void);
|
||||
extern uint64 sys_sigreturn(void);
|
||||
|
||||
// An array mapping syscall numbers from syscall.h
|
||||
// to the function that handles the system call.
|
||||
@@ -128,8 +126,6 @@ static uint64 (*syscalls[])(void) = {
|
||||
[SYS_link] sys_link,
|
||||
[SYS_mkdir] sys_mkdir,
|
||||
[SYS_close] sys_close,
|
||||
[SYS_sigalarm] sys_sigalarm,
|
||||
[SYS_sigreturn] sys_sigreturn,
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@@ -20,5 +20,3 @@
|
||||
#define SYS_link 19
|
||||
#define SYS_mkdir 20
|
||||
#define SYS_close 21
|
||||
#define SYS_sigalarm 22
|
||||
#define SYS_sigreturn 23
|
||||
|
||||
@@ -54,8 +54,6 @@ sys_sleep(void)
|
||||
int n;
|
||||
uint ticks0;
|
||||
|
||||
backtrace();
|
||||
|
||||
argint(0, &n);
|
||||
if(n < 0)
|
||||
n = 0;
|
||||
@@ -93,44 +91,3 @@ sys_uptime(void)
|
||||
release(&tickslock);
|
||||
return xticks;
|
||||
}
|
||||
|
||||
// sys_sigalarm函数用于设置进程的定时信号处理机制。
|
||||
// 参数:
|
||||
// alarm_cnt:定时器计数值,表示每经过alarm_cnt个时钟中断后触发一次信号处理。
|
||||
// addr:信号处理函数的用户空间地址。
|
||||
// 实现:
|
||||
// 1. 通过argint和argaddr获取用户传入的参数。
|
||||
// 2. 将进程的inter_cnt(中断计数器)清零。
|
||||
// 3. 保存信号处理函数地址和定时器计数值到进程结构体。
|
||||
// 4. 返回0,表示设置成功。
|
||||
|
||||
// sys_sigreturn函数用于在信号处理函数执行完毕后恢复进程的上下文。
|
||||
// 实现:
|
||||
// 1. 获取当前进程指针。
|
||||
// 2. 将trapframe恢复为信号处理前保存的pre_trapframe,恢复进程上下文。
|
||||
// 3. 将inter_cnt(中断计数器)清零,重新计数。
|
||||
// 4. 返回信号处理前a0寄存器的值,作为系统调用的返回值。
|
||||
uint64
|
||||
sys_sigalarm(void)
|
||||
{
|
||||
int alarm_cnt;
|
||||
uint64 addr;
|
||||
struct proc *p = myproc();
|
||||
argint(0, &alarm_cnt);
|
||||
argaddr(1, &addr);
|
||||
|
||||
p->inter_cnt = 0;
|
||||
p->handler = addr;
|
||||
p->alarm_cnt = alarm_cnt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_sigreturn(void)
|
||||
{
|
||||
struct proc* p = myproc();
|
||||
*p->trapframe = *p->pre_trapframe;
|
||||
p->inter_cnt = 0;
|
||||
return p->pre_trapframe->a0;
|
||||
}
|
||||
|
||||
@@ -76,21 +76,9 @@ usertrap(void)
|
||||
if(killed(p))
|
||||
exit(-1);
|
||||
|
||||
// 如果这是一个定时器中断,则让出CPU。
|
||||
if(which_dev == 2){
|
||||
// 当前进程的中断计数器加一。
|
||||
p->inter_cnt++;
|
||||
// 如果中断计数器达到设定的报警计数,并且报警计数大于0。
|
||||
if (p->inter_cnt == p->alarm_cnt && 0 < p->alarm_cnt) {
|
||||
// 备份当前trapframe到pre_trapframe,用于后续恢复。
|
||||
*p->pre_trapframe = *p->trapframe;
|
||||
// 将epc设置为用户定义的handler函数地址,返回用户态时会跳转到handler执行。
|
||||
p->trapframe->epc = p->handler;
|
||||
} else {
|
||||
// 否则让出CPU,进行进程调度。
|
||||
yield();
|
||||
}
|
||||
}
|
||||
// give up the CPU if this is a timer interrupt.
|
||||
if(which_dev == 2)
|
||||
yield();
|
||||
|
||||
usertrapret();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user