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.
This commit is contained in:
parent
abf847a083
commit
fbb4c09444
7 changed files with 97 additions and 62 deletions
1
defs.h
1
defs.h
|
@ -108,6 +108,7 @@ void exit(void);
|
||||||
int fork(void);
|
int fork(void);
|
||||||
int growproc(int);
|
int growproc(int);
|
||||||
int kill(int);
|
int kill(int);
|
||||||
|
struct proc* myproc();
|
||||||
void pinit(void);
|
void pinit(void);
|
||||||
void procdump(void);
|
void procdump(void);
|
||||||
void scheduler(void) __attribute__((noreturn));
|
void scheduler(void) __attribute__((noreturn));
|
||||||
|
|
15
exec.c
15
exec.c
|
@ -17,6 +17,7 @@ exec(char *path, char **argv)
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
struct proghdr ph;
|
struct proghdr ph;
|
||||||
pde_t *pgdir, *oldpgdir;
|
pde_t *pgdir, *oldpgdir;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
begin_op();
|
begin_op();
|
||||||
|
|
||||||
|
@ -90,15 +91,15 @@ exec(char *path, char **argv)
|
||||||
for(last=s=path; *s; s++)
|
for(last=s=path; *s; s++)
|
||||||
if(*s == '/')
|
if(*s == '/')
|
||||||
last = s+1;
|
last = s+1;
|
||||||
safestrcpy(myproc()->name, last, sizeof(myproc()->name));
|
safestrcpy(curproc->name, last, sizeof(curproc->name));
|
||||||
|
|
||||||
// Commit to the user image.
|
// Commit to the user image.
|
||||||
oldpgdir = myproc()->pgdir;
|
oldpgdir = curproc->pgdir;
|
||||||
myproc()->pgdir = pgdir;
|
curproc->pgdir = pgdir;
|
||||||
myproc()->sz = sz;
|
curproc->sz = sz;
|
||||||
myproc()->tf->eip = elf.entry; // main
|
curproc->tf->eip = elf.entry; // main
|
||||||
myproc()->tf->esp = sp;
|
curproc->tf->esp = sp;
|
||||||
switchuvm(myproc());
|
switchuvm(curproc);
|
||||||
freevm(oldpgdir);
|
freevm(oldpgdir);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
99
proc.c
99
proc.c
|
@ -26,14 +26,23 @@ pinit(void)
|
||||||
initlock(&ptable.lock, "ptable");
|
initlock(&ptable.lock, "ptable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX get rid off?
|
||||||
int
|
int
|
||||||
cpuid() {
|
cpuid() {
|
||||||
return mycpu()-cpus;
|
return mycpu()-cpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// Disable interrupts so that we are not rescheduled
|
||||||
setproc(struct proc* p) {
|
// while reading proc from the cpu structure
|
||||||
mycpu()->proc = p;
|
struct proc*
|
||||||
|
myproc(void) {
|
||||||
|
struct cpu *c;
|
||||||
|
struct proc *p;
|
||||||
|
pushcli();
|
||||||
|
c = mycpu();
|
||||||
|
p = c->proc;
|
||||||
|
popcli();
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
//PAGEBREAK: 32
|
//PAGEBREAK: 32
|
||||||
|
@ -130,17 +139,18 @@ int
|
||||||
growproc(int n)
|
growproc(int n)
|
||||||
{
|
{
|
||||||
uint sz;
|
uint sz;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
sz = myproc()->sz;
|
sz = curproc->sz;
|
||||||
if(n > 0){
|
if(n > 0){
|
||||||
if((sz = allocuvm(myproc()->pgdir, sz, sz + n)) == 0)
|
if((sz = allocuvm(curproc->pgdir, sz, sz + n)) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
} else if(n < 0){
|
} else if(n < 0){
|
||||||
if((sz = deallocuvm(myproc()->pgdir, sz, sz + n)) == 0)
|
if((sz = deallocuvm(curproc->pgdir, sz, sz + n)) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
myproc()->sz = sz;
|
curproc->sz = sz;
|
||||||
switchuvm(myproc());
|
switchuvm(curproc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +162,7 @@ fork(void)
|
||||||
{
|
{
|
||||||
int i, pid;
|
int i, pid;
|
||||||
struct proc *np;
|
struct proc *np;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
// Allocate process.
|
// Allocate process.
|
||||||
if((np = allocproc()) == 0){
|
if((np = allocproc()) == 0){
|
||||||
|
@ -159,25 +170,25 @@ fork(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy process state from proc.
|
// Copy process state from proc.
|
||||||
if((np->pgdir = copyuvm(myproc()->pgdir, myproc()->sz)) == 0){
|
if((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0){
|
||||||
kfree(np->kstack);
|
kfree(np->kstack);
|
||||||
np->kstack = 0;
|
np->kstack = 0;
|
||||||
np->state = UNUSED;
|
np->state = UNUSED;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
np->sz = myproc()->sz;
|
np->sz = curproc->sz;
|
||||||
np->parent = myproc();
|
np->parent = curproc;
|
||||||
*np->tf = *myproc()->tf;
|
*np->tf = *curproc->tf;
|
||||||
|
|
||||||
// Clear %eax so that fork returns 0 in the child.
|
// Clear %eax so that fork returns 0 in the child.
|
||||||
np->tf->eax = 0;
|
np->tf->eax = 0;
|
||||||
|
|
||||||
for(i = 0; i < NOFILE; i++)
|
for(i = 0; i < NOFILE; i++)
|
||||||
if(myproc()->ofile[i])
|
if(curproc->ofile[i])
|
||||||
np->ofile[i] = filedup(myproc()->ofile[i]);
|
np->ofile[i] = filedup(curproc->ofile[i]);
|
||||||
np->cwd = idup(myproc()->cwd);
|
np->cwd = idup(curproc->cwd);
|
||||||
|
|
||||||
safestrcpy(np->name, myproc()->name, sizeof(myproc()->name));
|
safestrcpy(np->name, curproc->name, sizeof(curproc->name));
|
||||||
|
|
||||||
pid = np->pid;
|
pid = np->pid;
|
||||||
|
|
||||||
|
@ -196,33 +207,34 @@ fork(void)
|
||||||
void
|
void
|
||||||
exit(void)
|
exit(void)
|
||||||
{
|
{
|
||||||
|
struct proc *curproc = myproc();
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if(myproc() == initproc)
|
if(curproc == initproc)
|
||||||
panic("init exiting");
|
panic("init exiting");
|
||||||
|
|
||||||
// Close all open files.
|
// Close all open files.
|
||||||
for(fd = 0; fd < NOFILE; fd++){
|
for(fd = 0; fd < NOFILE; fd++){
|
||||||
if(myproc()->ofile[fd]){
|
if(curproc->ofile[fd]){
|
||||||
fileclose(myproc()->ofile[fd]);
|
fileclose(curproc->ofile[fd]);
|
||||||
myproc()->ofile[fd] = 0;
|
curproc->ofile[fd] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
begin_op();
|
begin_op();
|
||||||
iput(myproc()->cwd);
|
iput(curproc->cwd);
|
||||||
end_op();
|
end_op();
|
||||||
myproc()->cwd = 0;
|
curproc->cwd = 0;
|
||||||
|
|
||||||
acquire(&ptable.lock);
|
acquire(&ptable.lock);
|
||||||
|
|
||||||
// Parent might be sleeping in wait().
|
// Parent might be sleeping in wait().
|
||||||
wakeup1(myproc()->parent);
|
wakeup1(curproc->parent);
|
||||||
|
|
||||||
// Pass abandoned children to init.
|
// Pass abandoned children to init.
|
||||||
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
|
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
|
||||||
if(p->parent == myproc()){
|
if(p->parent == curproc){
|
||||||
p->parent = initproc;
|
p->parent = initproc;
|
||||||
if(p->state == ZOMBIE)
|
if(p->state == ZOMBIE)
|
||||||
wakeup1(initproc);
|
wakeup1(initproc);
|
||||||
|
@ -230,7 +242,7 @@ exit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jump into the scheduler, never to return.
|
// Jump into the scheduler, never to return.
|
||||||
myproc()->state = ZOMBIE;
|
curproc->state = ZOMBIE;
|
||||||
sched();
|
sched();
|
||||||
panic("zombie exit");
|
panic("zombie exit");
|
||||||
}
|
}
|
||||||
|
@ -242,13 +254,14 @@ wait(void)
|
||||||
{
|
{
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
int havekids, pid;
|
int havekids, pid;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
acquire(&ptable.lock);
|
acquire(&ptable.lock);
|
||||||
for(;;){
|
for(;;){
|
||||||
// Scan through table looking for exited children.
|
// Scan through table looking for exited children.
|
||||||
havekids = 0;
|
havekids = 0;
|
||||||
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
|
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
|
||||||
if(p->parent != myproc())
|
if(p->parent != curproc)
|
||||||
continue;
|
continue;
|
||||||
havekids = 1;
|
havekids = 1;
|
||||||
if(p->state == ZOMBIE){
|
if(p->state == ZOMBIE){
|
||||||
|
@ -268,13 +281,13 @@ wait(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// No point waiting if we don't have any children.
|
// No point waiting if we don't have any children.
|
||||||
if(!havekids || myproc()->killed){
|
if(!havekids || curproc->killed){
|
||||||
release(&ptable.lock);
|
release(&ptable.lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for children to exit. (See wakeup1 call in proc_exit.)
|
// Wait for children to exit. (See wakeup1 call in proc_exit.)
|
||||||
sleep(myproc(), &ptable.lock); //DOC: wait-sleep
|
sleep(curproc, &ptable.lock); //DOC: wait-sleep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,6 +303,7 @@ void
|
||||||
scheduler(void)
|
scheduler(void)
|
||||||
{
|
{
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
struct cpu *c = mycpu();
|
||||||
|
|
||||||
for(;;){
|
for(;;){
|
||||||
// Enable interrupts on this processor.
|
// Enable interrupts on this processor.
|
||||||
|
@ -304,15 +318,18 @@ scheduler(void)
|
||||||
// Switch to chosen process. It is the process's job
|
// Switch to chosen process. It is the process's job
|
||||||
// to release ptable.lock and then reacquire it
|
// to release ptable.lock and then reacquire it
|
||||||
// before jumping back to us.
|
// before jumping back to us.
|
||||||
setproc(p);
|
c->proc = p;
|
||||||
switchuvm(p);
|
switchuvm(p);
|
||||||
p->state = RUNNING;
|
p->state = RUNNING;
|
||||||
swtch(&(mycpu()->scheduler), p->context);
|
p->cpu = c;
|
||||||
|
// cprintf("%d: switch to %d\n", c-cpus, p->pid);
|
||||||
|
swtch(&(p->cpu->scheduler), p->context);
|
||||||
switchkvm();
|
switchkvm();
|
||||||
|
|
||||||
// Process is done running for now.
|
// Process is done running for now.
|
||||||
// It should have changed its p->state before coming back.
|
// It should have changed its p->state before coming back.
|
||||||
setproc(0);
|
c->proc = 0;
|
||||||
|
p->cpu = 0;
|
||||||
}
|
}
|
||||||
release(&ptable.lock);
|
release(&ptable.lock);
|
||||||
|
|
||||||
|
@ -330,17 +347,20 @@ void
|
||||||
sched(void)
|
sched(void)
|
||||||
{
|
{
|
||||||
int intena;
|
int intena;
|
||||||
|
struct proc *p = myproc();
|
||||||
|
|
||||||
if(!holding(&ptable.lock))
|
if(!holding(&ptable.lock))
|
||||||
panic("sched ptable.lock");
|
panic("sched ptable.lock");
|
||||||
if(mycpu()->ncli != 1)
|
if(mycpu()->ncli != 1)
|
||||||
panic("sched locks");
|
panic("sched locks");
|
||||||
if(myproc()->state == RUNNING)
|
if(p->state == RUNNING)
|
||||||
panic("sched running");
|
panic("sched running");
|
||||||
if(readeflags()&FL_IF)
|
if(readeflags()&FL_IF)
|
||||||
panic("sched interruptible");
|
panic("sched interruptible");
|
||||||
intena = mycpu()->intena;
|
intena = mycpu()->intena;
|
||||||
swtch(&myproc()->context, mycpu()->scheduler);
|
// cprintf("%d: before swtch %d %x\n", p->cpu-cpus, p->pid, * (int *) 0x1d);
|
||||||
|
swtch(&p->context, p->cpu->scheduler);
|
||||||
|
// cprintf("%d/%d: after swtch %d %x\n", cpuid(), p->cpu-cpus, p->pid, * (int *) 0x1d);
|
||||||
mycpu()->intena = intena;
|
mycpu()->intena = intena;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +400,9 @@ forkret(void)
|
||||||
void
|
void
|
||||||
sleep(void *chan, struct spinlock *lk)
|
sleep(void *chan, struct spinlock *lk)
|
||||||
{
|
{
|
||||||
if(myproc() == 0)
|
struct proc *p = myproc();
|
||||||
|
|
||||||
|
if(p == 0)
|
||||||
panic("sleep");
|
panic("sleep");
|
||||||
|
|
||||||
if(lk == 0)
|
if(lk == 0)
|
||||||
|
@ -397,12 +419,15 @@ sleep(void *chan, struct spinlock *lk)
|
||||||
release(lk);
|
release(lk);
|
||||||
}
|
}
|
||||||
// Go to sleep.
|
// Go to sleep.
|
||||||
myproc()->chan = chan;
|
p->chan = chan;
|
||||||
myproc()->state = SLEEPING;
|
p->state = SLEEPING;
|
||||||
|
|
||||||
|
// cprintf("sleep %d\n", p->pid);
|
||||||
|
|
||||||
sched();
|
sched();
|
||||||
|
|
||||||
// Tidy up.
|
// Tidy up.
|
||||||
myproc()->chan = 0;
|
p->chan = 0;
|
||||||
|
|
||||||
// Reacquire original lock.
|
// Reacquire original lock.
|
||||||
if(lk != &ptable.lock){ //DOC: sleeplock2
|
if(lk != &ptable.lock){ //DOC: sleeplock2
|
||||||
|
|
3
proc.h
3
proc.h
|
@ -30,12 +30,14 @@ mycpu(void) {
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static inline struct proc*
|
static inline struct proc*
|
||||||
myproc(void) {
|
myproc(void) {
|
||||||
struct proc *proc;
|
struct proc *proc;
|
||||||
asm("movl %%gs:4, %0" : "=r"(proc));
|
asm("movl %%gs:4, %0" : "=r"(proc));
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//PAGEBREAK: 17
|
//PAGEBREAK: 17
|
||||||
|
@ -74,6 +76,7 @@ struct proc {
|
||||||
struct file *ofile[NOFILE]; // Open files
|
struct file *ofile[NOFILE]; // Open files
|
||||||
struct inode *cwd; // Current directory
|
struct inode *cwd; // Current directory
|
||||||
char name[16]; // Process name (debugging)
|
char name[16]; // Process name (debugging)
|
||||||
|
struct cpu *cpu; // If running, which cpu.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process memory is laid out contiguously, low addresses first:
|
// Process memory is laid out contiguously, low addresses first:
|
||||||
|
|
21
syscall.c
21
syscall.c
|
@ -17,7 +17,9 @@
|
||||||
int
|
int
|
||||||
fetchint(uint addr, int *ip)
|
fetchint(uint addr, int *ip)
|
||||||
{
|
{
|
||||||
if(addr >= myproc()->sz || addr+4 > myproc()->sz)
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
|
if(addr >= curproc->sz || addr+4 > curproc->sz)
|
||||||
return -1;
|
return -1;
|
||||||
*ip = *(int*)(addr);
|
*ip = *(int*)(addr);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -30,11 +32,12 @@ int
|
||||||
fetchstr(uint addr, char **pp)
|
fetchstr(uint addr, char **pp)
|
||||||
{
|
{
|
||||||
char *s, *ep;
|
char *s, *ep;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
if(addr >= myproc()->sz)
|
if(addr >= curproc->sz)
|
||||||
return -1;
|
return -1;
|
||||||
*pp = (char*)addr;
|
*pp = (char*)addr;
|
||||||
ep = (char*)myproc()->sz;
|
ep = (char*)curproc->sz;
|
||||||
for(s = *pp; s < ep; s++){
|
for(s = *pp; s < ep; s++){
|
||||||
if(*s == 0)
|
if(*s == 0)
|
||||||
return s - *pp;
|
return s - *pp;
|
||||||
|
@ -56,10 +59,11 @@ int
|
||||||
argptr(int n, char **pp, int size)
|
argptr(int n, char **pp, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
if(argint(n, &i) < 0)
|
if(argint(n, &i) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(size < 0 || (uint)i >= myproc()->sz || (uint)i+size > myproc()->sz)
|
if(size < 0 || (uint)i >= curproc->sz || (uint)i+size > curproc->sz)
|
||||||
return -1;
|
return -1;
|
||||||
*pp = (char*)i;
|
*pp = (char*)i;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -128,13 +132,14 @@ void
|
||||||
syscall(void)
|
syscall(void)
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
num = myproc()->tf->eax;
|
num = curproc->tf->eax;
|
||||||
if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
|
if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
|
||||||
myproc()->tf->eax = syscalls[num]();
|
curproc->tf->eax = syscalls[num]();
|
||||||
} else {
|
} else {
|
||||||
cprintf("%d %s: unknown sys call %d\n",
|
cprintf("%d %s: unknown sys call %d\n",
|
||||||
myproc()->pid, myproc()->name, num);
|
curproc->pid, curproc->name, num);
|
||||||
myproc()->tf->eax = -1;
|
curproc->tf->eax = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
sysfile.c
10
sysfile.c
|
@ -41,10 +41,11 @@ static int
|
||||||
fdalloc(struct file *f)
|
fdalloc(struct file *f)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
for(fd = 0; fd < NOFILE; fd++){
|
for(fd = 0; fd < NOFILE; fd++){
|
||||||
if(myproc()->ofile[fd] == 0){
|
if(curproc->ofile[fd] == 0){
|
||||||
myproc()->ofile[fd] = f;
|
curproc->ofile[fd] = f;
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,6 +374,7 @@ sys_chdir(void)
|
||||||
{
|
{
|
||||||
char *path;
|
char *path;
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
|
struct proc *curproc = myproc();
|
||||||
|
|
||||||
begin_op();
|
begin_op();
|
||||||
if(argstr(0, &path) < 0 || (ip = namei(path)) == 0){
|
if(argstr(0, &path) < 0 || (ip = namei(path)) == 0){
|
||||||
|
@ -386,9 +388,9 @@ sys_chdir(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
iunlock(ip);
|
iunlock(ip);
|
||||||
iput(myproc()->cwd);
|
iput(curproc->cwd);
|
||||||
end_op();
|
end_op();
|
||||||
myproc()->cwd = ip;
|
curproc->cwd = ip;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
vm.c
4
vm.c
|
@ -27,13 +27,11 @@ seginit(void)
|
||||||
c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, DPL_USER);
|
c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, DPL_USER);
|
||||||
c->gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER);
|
c->gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER);
|
||||||
c->cpu = c;
|
c->cpu = c;
|
||||||
|
c->proc = 0;
|
||||||
// Map cpu and proc -- these are private per cpu.
|
// Map cpu and proc -- these are private per cpu.
|
||||||
c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 4, 0);
|
c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 4, 0);
|
||||||
lgdt(c->gdt, sizeof(c->gdt));
|
lgdt(c->gdt, sizeof(c->gdt));
|
||||||
loadgs(SEG_KCPU << 3);
|
loadgs(SEG_KCPU << 3);
|
||||||
// Initialize cpu-local storage.
|
|
||||||
// setcpu(c);
|
|
||||||
setproc(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the address of the PTE in page table pgdir
|
// Return the address of the PTE in page table pgdir
|
||||||
|
|
Loading…
Reference in a new issue