cow lab initialized

This commit is contained in:
2025-06-28 09:57:36 +08:00
parent 7c42fbed17
commit c6fa25504f
25 changed files with 351 additions and 617 deletions

View File

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

View File

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

View File

@@ -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;

View File

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

View File

@@ -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()

View File

@@ -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

View File

@@ -20,5 +20,3 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_sigalarm 22
#define SYS_sigreturn 23

View File

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

View File

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