proc.h (3281B)
1 // Segments in proc->gdt. 2 #define NSEGS 7 3 4 // Per-CPU state 5 struct cpu { 6 uchar id; // index into cpus[] below 7 uchar apicid; // Local APIC ID 8 struct context *scheduler; // swtch() here to enter scheduler 9 struct taskstate ts; // Used by x86 to find stack for interrupt 10 struct segdesc gdt[NSEGS]; // x86 global descriptor table 11 volatile uint started; // Has the CPU started? 12 int ncli; // Depth of pushcli nesting. 13 int intena; // Were interrupts enabled before pushcli? 14 15 // Cpu-local storage variables; see below 16 #if X64 17 void *local; 18 #else 19 struct cpu *cpu; 20 struct proc *proc; // The currently-running process. 21 #endif 22 }; 23 24 extern struct cpu cpus[NCPU]; 25 extern int ncpu; 26 27 // Per-CPU variables, holding pointers to the 28 // current cpu and to the current process. 29 // The asm suffix tells gcc to use "%gs:0" to refer to cpu 30 // and "%gs:4" to refer to proc. seginit sets up the 31 // %gs segment register so that %gs refers to the memory 32 // holding those two variables in the local cpu's struct cpu. 33 // This is similar to how thread-local variables are implemented 34 // in thread libraries such as Linux pthreads. 35 #if X64 36 extern __thread struct cpu *cpu; 37 extern __thread struct proc *proc; 38 #else 39 extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()] 40 extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc 41 #endif 42 43 //PAGEBREAK: 17 44 // Saved registers for kernel context switches. 45 // Don't need to save all the segment registers (%cs, etc), 46 // because they are constant across kernel contexts. 47 // Don't need to save %eax, %ecx, %edx, because the 48 // x86 convention is that the caller has saved them. 49 // Contexts are stored at the bottom of the stack they 50 // describe; the stack pointer is the address of the context. 51 // The layout of the context matches the layout of the stack in swtch.S 52 // at the "Switch stacks" comment. Switch doesn't save eip explicitly, 53 // but it is on the stack and allocproc() manipulates it. 54 #if X64 55 struct context { 56 uintp r15; 57 uintp r14; 58 uintp r13; 59 uintp r12; 60 uintp r11; 61 uintp rbx; 62 uintp ebp; //rbp 63 uintp eip; //rip; 64 }; 65 #else 66 struct context { 67 uintp edi; 68 uintp esi; 69 uintp ebx; 70 uintp ebp; 71 uintp eip; 72 }; 73 #endif 74 75 enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; 76 77 // Per-process state 78 struct proc { 79 uintp sz; // Size of process memory (bytes) 80 pde_t* pgdir; // Page table 81 char *kstack; // Bottom of kernel stack for this process 82 enum procstate state; // Process state 83 volatile int pid; // Process ID 84 struct proc *parent; // Parent process 85 struct trapframe *tf; // Trap frame for current syscall 86 struct context *context; // swtch() here to run process 87 void *chan; // If non-zero, sleeping on chan 88 int killed; // If non-zero, have been killed 89 struct file *ofile[NOFILE]; // Open files 90 struct inode *cwd; // Current directory 91 char name[16]; // Process name (debugging) 92 }; 93 94 // Process memory is laid out contiguously, low addresses first: 95 // text 96 // original data and bss 97 // fixed-size stack 98 // expandable heap