// holding those two variables in the local cpu's struct cpu.
// This is similar to how thread-local variables are implemented
// in thread libraries such as Linux pthreads.
+//
+// One must be very careful with cpu as we might migrate; that is, in
+// general, it is only safe to access this variable and *do* anything with
+// it while local preemption is disabled.
+//
+// proc is *observably constant* from a particular proc's perspective, on
+// the other hand (the scheduler always restores its value) and so is in
+// general safe to access without holding any locks.
extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()]
extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc
}
//PAGEBREAK: 41
+// This is here so you can break on it in gdb
+static void
+trap_exit()
+{
+ sti();
+ exit();
+}
void
trap(struct trapframe *tf)
{
// (If it is still executing in the kernel, let it keep running
// until it gets to the regular system call return.)
if(proc && proc->killed && (tf->cs&3) == DPL_USER)
- exit();
+ trap_exit();
// Force process to give up CPU on clock tick.
// If interrupts were on while locks held, would need to check nlock.
// Check if the process has been killed since we yielded
if(proc && proc->killed && (tf->cs&3) == DPL_USER)
- exit();
+ trap_exit();
}