From abf847a083888bbed4260ecacf849ea19f23e810 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Tue, 31 Jan 2017 17:47:16 -0500 Subject: Start of an experiment to remove the use of gs for cpu local variables. --- proc.h | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'proc.h') diff --git a/proc.h b/proc.h index 7352805..38a2d32 100644 --- a/proc.h +++ b/proc.h @@ -7,25 +7,36 @@ struct cpu { volatile uint started; // 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. + // Per-CPU variables, holding pointers to the current cpu and to the current + // process (see cpu() and proc() in proc.c) + struct cpu *cpu; // On cpu 0, cpu = &cpus[0]; on cpu 1, cpu=&cpus[1], etc. + struct proc *proc; // The currently-running process on this cpu }; 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 + +static inline struct cpu* +mycpu(void) { + struct cpu *cpu; + asm("movl %%gs:0, %0" : "=r"(cpu)); + return cpu; +} + +static inline struct proc* +myproc(void) { + struct proc *proc; + asm("movl %%gs:4, %0" : "=r"(proc)); + return proc; +} + //PAGEBREAK: 17 // Saved registers for kernel context switches. -- cgit v1.2.3 From fbb4c0944422f860484142010bb9f366f3e87bf8 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Tue, 31 Jan 2017 20:21:14 -0500 Subject: Read curproc from cpu structure, but be careful because after a schedule event myproc() points to a different thread. myproc(); sched(); myproc(); // this proc maybe different than the one before sched Thus, in a function that operates on one thread better to retrieve the current process once at the start of the function. --- proc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'proc.h') diff --git a/proc.h b/proc.h index 38a2d32..7047d54 100644 --- a/proc.h +++ b/proc.h @@ -30,12 +30,14 @@ mycpu(void) { return cpu; } +#if 0 static inline struct proc* myproc(void) { struct proc *proc; asm("movl %%gs:4, %0" : "=r"(proc)); return proc; } +#endif //PAGEBREAK: 17 @@ -74,6 +76,7 @@ struct proc { struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) + struct cpu *cpu; // If running, which cpu. }; // Process memory is laid out contiguously, low addresses first: -- cgit v1.2.3 From ed396c068b881877330f7d40bfce02db9b1199b3 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Wed, 1 Feb 2017 18:04:13 -0500 Subject: Eliminate code for gs trick to track per-cpu state. We rely on lapiccpunum() to find a per-cpu id with which we locate a cpu's cpu struct. --- proc.h | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) (limited to 'proc.h') diff --git a/proc.h b/proc.h index 7047d54..1647114 100644 --- a/proc.h +++ b/proc.h @@ -7,39 +7,12 @@ struct cpu { volatile uint started; // Has the CPU started? int ncli; // Depth of pushcli nesting. int intena; // Were interrupts enabled before pushcli? - // Per-CPU variables, holding pointers to the current cpu and to the current - // process (see cpu() and proc() in proc.c) - struct cpu *cpu; // On cpu 0, cpu = &cpus[0]; on cpu 1, cpu=&cpus[1], etc. - struct proc *proc; // The currently-running process on this cpu + struct proc *proc; // The process running on this cpu or null }; extern struct cpu cpus[NCPU]; extern int ncpu; -// 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. - -static inline struct cpu* -mycpu(void) { - struct cpu *cpu; - asm("movl %%gs:0, %0" : "=r"(cpu)); - return cpu; -} - -#if 0 -static inline struct proc* -myproc(void) { - struct proc *proc; - asm("movl %%gs:4, %0" : "=r"(proc)); - return proc; -} -#endif - - //PAGEBREAK: 17 // Saved registers for kernel context switches. // Don't need to save all the segment registers (%cs, etc), @@ -76,7 +49,6 @@ struct proc { struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) - struct cpu *cpu; // If running, which cpu. }; // Process memory is laid out contiguously, low addresses first: -- cgit v1.2.3