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