xv6-65oo2/proc.h

83 lines
3.2 KiB
C
Raw Normal View History

// Segments in proc->gdt.
// Also known to bootasm.S and trapasm.S
2006-09-07 14:12:30 +00:00
#define SEG_KCODE 1 // kernel code
#define SEG_KDATA 2 // kernel data+stack
#define SEG_KCPU 3 // kernel per-cpu data
#define SEG_UCODE 4 // user code
#define SEG_UDATA 5 // user data+stack
#define SEG_TSS 6 // this process's task state
#define NSEGS 7
2006-06-12 15:22:12 +00:00
// Per-CPU state
struct cpu {
uchar id; // Local APIC ID; index into cpus[] below
struct context *scheduler; // swtch() here to enter scheduler
struct taskstate ts; // Used by x86 to find stack for interrupt
struct segdesc gdt[NSEGS]; // x86 global descriptor table
volatile uint booted; // Has the CPU started?
int ncli; // Depth of pushcli nesting.
int intena; // Were interrupts enabled before pushcli?
// Cpu-local storage variables; see below
struct cpu *cpu;
struct proc *proc; // The currently-running process.
};
extern struct cpu cpus[NCPU];
extern int ncpu;
// Per-CPU variables, holding pointers to the
// current cpu and to the current process.
// The asm suffix tells gcc to use "%gs:0" to refer to cpu
// and "%gs:4" to refer to proc. seginit sets up the
// %gs segment register so that %gs refers to the memory
// 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.
extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()]
extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc
//PAGEBREAK: 17
2006-09-07 14:12:30 +00:00
// Saved registers for kernel context switches.
2008-10-15 05:14:10 +00:00
// Don't need to save all the segment registers (%cs, etc),
2006-09-07 14:12:30 +00:00
// because they are constant across kernel contexts.
// Don't need to save %eax, %ecx, %edx, because the
// x86 convention is that the caller has saved them.
// Contexts are stored at the bottom of the stack they
// describe; the stack pointer is the address of the context.
2009-10-07 19:31:55 +00:00
// The layout of the context matches the layout of the stack in swtch.S
// at the "Switch stacks" comment. Switch doesn't save eip explicitly,
2009-10-07 21:42:14 +00:00
// but it is on the stack and allocproc() manipulates it.
2007-08-28 12:48:33 +00:00
struct context {
2008-10-15 05:14:10 +00:00
uint edi;
uint esi;
uint ebx;
uint ebp;
uint eip;
2006-07-11 01:07:40 +00:00
};
enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
2006-09-07 14:12:30 +00:00
// Per-process state
struct proc {
2008-10-15 05:15:32 +00:00
uint sz; // Size of process memory (bytes)
pde_t* pgdir; // Page table
2008-10-15 05:15:32 +00:00
char *kstack; // Bottom of kernel stack for this process
enum procstate state; // Process state
2009-05-31 00:39:17 +00:00
volatile int pid; // Process ID
2008-10-15 05:15:32 +00:00
struct proc *parent; // Parent process
struct trapframe *tf; // Trap frame for current syscall
struct context *context; // swtch() here to run process
2008-10-15 05:15:32 +00:00
void *chan; // If non-zero, sleeping on chan
int killed; // If non-zero, have been killed
2006-09-07 14:12:30 +00:00
struct file *ofile[NOFILE]; // Open files
2008-10-15 05:15:32 +00:00
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
2006-06-12 15:22:12 +00:00
};
2007-08-24 14:56:17 +00:00
// Process memory is laid out contiguously, low addresses first:
2006-09-07 14:12:30 +00:00
// text
// original data and bss
// fixed-size stack
// expandable heap