cleaner swtch.S
This commit is contained in:
parent
228e500a0c
commit
c100d9ee2d
4 changed files with 31 additions and 41 deletions
2
defs.h
2
defs.h
|
@ -107,7 +107,7 @@ void wakeup(void*);
|
|||
void yield(void);
|
||||
|
||||
// swtch.S
|
||||
void swtch(struct context*, struct context*);
|
||||
void swtch(struct context**, struct context**);
|
||||
|
||||
// spinlock.c
|
||||
void acquire(struct spinlock*);
|
||||
|
|
8
proc.c
8
proc.c
|
@ -137,9 +137,9 @@ copyproc(struct proc *p)
|
|||
}
|
||||
|
||||
// Set up new context to start executing at forkret (see below).
|
||||
memset(&np->context, 0, sizeof(np->context));
|
||||
np->context.eip = (uint)forkret;
|
||||
np->context.esp = (uint)np->tf;
|
||||
np->context = (struct context *)np->tf - 1;
|
||||
memset(np->context, 0, sizeof(*np->context));
|
||||
np->context->eip = (uint)forkret;
|
||||
|
||||
// Clear %eax so that fork system call returns 0 in child.
|
||||
np->tf->eax = 0;
|
||||
|
@ -477,7 +477,7 @@ procdump(void)
|
|||
state = "???";
|
||||
cprintf("%d %s %s", p->pid, state, p->name);
|
||||
if(p->state == SLEEPING){
|
||||
getcallerpcs((uint*)p->context.ebp+2, pc);
|
||||
getcallerpcs((uint*)p->context->ebp+2, pc);
|
||||
for(j=0; j<10 && pc[j] != 0; j++)
|
||||
cprintf(" %p", pc[j]);
|
||||
}
|
||||
|
|
26
proc.h
26
proc.h
|
@ -7,21 +7,17 @@
|
|||
#define NSEGS 6
|
||||
|
||||
// Saved registers for kernel context switches.
|
||||
// Don't need to save all the %fs etc. segment registers,
|
||||
// Don't need to save all the segment registers (%cs, etc),
|
||||
// because they are constant across kernel contexts.
|
||||
// Save all the regular registers so we don't need to care
|
||||
// which are caller save, but not the return register %eax.
|
||||
// (Not saving %eax just simplifies the switching code.)
|
||||
// Stack pointer is encoded in the address of context,
|
||||
// which must be placed at the bottom of the stack.
|
||||
// The layout of context must match code in swtch.S.
|
||||
struct context {
|
||||
int eip;
|
||||
int esp;
|
||||
int ebx;
|
||||
int ecx;
|
||||
int edx;
|
||||
int esi;
|
||||
int edi;
|
||||
int ebp;
|
||||
uint edi;
|
||||
uint esi;
|
||||
uint ebx;
|
||||
uint ebp;
|
||||
uint eip;
|
||||
};
|
||||
|
||||
enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
|
||||
|
@ -38,8 +34,8 @@ struct proc {
|
|||
int killed; // If non-zero, have been killed
|
||||
struct file *ofile[NOFILE]; // Open files
|
||||
struct inode *cwd; // Current directory
|
||||
struct context context; // Switch here to run process
|
||||
struct trapframe *tf; // Trap frame for current interrupt
|
||||
struct context *context; // Switch here to run process
|
||||
struct trapframe *tf; // Trap frame for current syscall
|
||||
char name[16]; // Process name (debugging)
|
||||
};
|
||||
|
||||
|
@ -53,7 +49,7 @@ struct proc {
|
|||
struct cpu {
|
||||
uchar apicid; // Local APIC ID
|
||||
struct proc *curproc; // Process currently running.
|
||||
struct context context; // Switch here to enter scheduler
|
||||
struct context *context; // Switch 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?
|
||||
|
|
36
swtch.S
36
swtch.S
|
@ -1,32 +1,26 @@
|
|||
# void swtch(struct context *old, struct context *new);
|
||||
# void swtch(struct context **old, struct context **new);
|
||||
#
|
||||
# Save current register context in old
|
||||
# and then load register context from new.
|
||||
|
||||
.globl swtch
|
||||
swtch:
|
||||
# Save old registers
|
||||
movl 4(%esp), %eax
|
||||
movl 8(%esp), %edx
|
||||
|
||||
popl 0(%eax) # %eip
|
||||
movl %esp, 4(%eax)
|
||||
movl %ebx, 8(%eax)
|
||||
movl %ecx, 12(%eax)
|
||||
movl %edx, 16(%eax)
|
||||
movl %esi, 20(%eax)
|
||||
movl %edi, 24(%eax)
|
||||
movl %ebp, 28(%eax)
|
||||
# Save old callee-save registers
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
# Load new registers
|
||||
movl 4(%esp), %eax # not 8(%esp) - popped return address above
|
||||
|
||||
movl 28(%eax), %ebp
|
||||
movl 24(%eax), %edi
|
||||
movl 20(%eax), %esi
|
||||
movl 16(%eax), %edx
|
||||
movl 12(%eax), %ecx
|
||||
movl 8(%eax), %ebx
|
||||
movl 4(%eax), %esp
|
||||
pushl 0(%eax) # %eip
|
||||
# Switch stacks
|
||||
movl %esp, (%eax)
|
||||
movl (%edx), %esp
|
||||
|
||||
# Load new callee-save registers
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
ret
|
||||
|
|
Loading…
Reference in a new issue