comment added
This commit is contained in:
@ -177,6 +177,7 @@ printfinit(void)
|
||||
pr.locking = 1;
|
||||
}
|
||||
|
||||
// 打印当前调用栈的返回地址,实现简单的函数回溯,用于调试。
|
||||
void
|
||||
backtrace(void)
|
||||
{
|
||||
@ -185,11 +186,12 @@ backtrace(void)
|
||||
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;
|
||||
pre_fp = *((uint64*)(fp - 16));
|
||||
ra = *(uint64 *)(fp - 8); // 取出返回地址
|
||||
printf("%p\n", (void*)ra); // 打印返回地址
|
||||
fp = pre_fp; // 更新fp为上一个fp
|
||||
pre_fp = *((uint64*)(fp - 16)); // 获取新的上一个fp
|
||||
}
|
||||
|
||||
ra = *(uint64 *)(fp - 8);
|
||||
|
||||
@ -132,6 +132,7 @@ found:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 为进程分配 pre_trapframe 空间,分配失败则释放进程资源并返回 0
|
||||
if((p->pre_trapframe = (struct trapframe *)kalloc()) == 0){
|
||||
freeproc(p);
|
||||
release(&p->lock);
|
||||
@ -166,6 +167,7 @@ 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;
|
||||
|
||||
@ -104,8 +104,8 @@ struct proc {
|
||||
struct file *ofile[NOFILE]; // Open files
|
||||
struct inode *cwd; // Current directory
|
||||
char name[16]; // Process name (debugging)
|
||||
int alarm_cnt; // Alarm count
|
||||
int inter_cnt; // interrupts count
|
||||
uint64 handler; // alarm func address
|
||||
int alarm_cnt; // Alarm count 触发alarm的时钟中断数量
|
||||
int inter_cnt; // interrupts count 需要统计的时钟中断的数量
|
||||
uint64 handler; // alarm func address 记录处理alarm的函数的地址
|
||||
struct trapframe *pre_trapframe;
|
||||
};
|
||||
|
||||
@ -338,6 +338,7 @@ r_ra()
|
||||
return x;
|
||||
}
|
||||
|
||||
// 读取当前帧指针(s0)寄存器的值
|
||||
static inline uint64
|
||||
r_fp()
|
||||
{
|
||||
|
||||
@ -94,6 +94,22 @@ sys_uptime(void)
|
||||
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)
|
||||
{
|
||||
|
||||
@ -76,13 +76,18 @@ usertrap(void)
|
||||
if(killed(p))
|
||||
exit(-1);
|
||||
|
||||
// give up the CPU if this is a timer interrupt.
|
||||
// 如果这是一个定时器中断,则让出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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user