try to handle a few of the possible out-of-memory errors in fork()
This commit is contained in:
parent
a8dd44cf59
commit
bc51626aab
|
@ -17,6 +17,7 @@ struct spinlock pid_lock;
|
||||||
|
|
||||||
extern void forkret(void);
|
extern void forkret(void);
|
||||||
static void wakeup1(struct proc *chan);
|
static void wakeup1(struct proc *chan);
|
||||||
|
static void freeproc(struct proc *p);
|
||||||
|
|
||||||
extern char trampoline[]; // trampoline.S
|
extern char trampoline[]; // trampoline.S
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ allocpid() {
|
||||||
// Look in the process table for an UNUSED proc.
|
// Look in the process table for an UNUSED proc.
|
||||||
// If found, initialize state required to run in the kernel,
|
// If found, initialize state required to run in the kernel,
|
||||||
// and return with p->lock held.
|
// and return with p->lock held.
|
||||||
// If there are no free procs, return 0.
|
// If there are no free procs, or a memory allocation fails, return 0.
|
||||||
static struct proc*
|
static struct proc*
|
||||||
allocproc(void)
|
allocproc(void)
|
||||||
{
|
{
|
||||||
|
@ -114,6 +115,11 @@ found:
|
||||||
|
|
||||||
// An empty user page table.
|
// An empty user page table.
|
||||||
p->pagetable = proc_pagetable(p);
|
p->pagetable = proc_pagetable(p);
|
||||||
|
if(p->pagetable == 0){
|
||||||
|
freeproc(p);
|
||||||
|
release(&p->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Set up new context to start executing at forkret,
|
// Set up new context to start executing at forkret,
|
||||||
// which returns to user space.
|
// which returns to user space.
|
||||||
|
@ -160,12 +166,19 @@ proc_pagetable(struct proc *p)
|
||||||
// at the highest user virtual address.
|
// at the highest user virtual address.
|
||||||
// only the supervisor uses it, on the way
|
// only the supervisor uses it, on the way
|
||||||
// to/from user space, so not PTE_U.
|
// to/from user space, so not PTE_U.
|
||||||
mappages(pagetable, TRAMPOLINE, PGSIZE,
|
if(mappages(pagetable, TRAMPOLINE, PGSIZE,
|
||||||
(uint64)trampoline, PTE_R | PTE_X);
|
(uint64)trampoline, PTE_R | PTE_X) < 0){
|
||||||
|
uvmfree(pagetable, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// map the trapframe just below TRAMPOLINE, for trampoline.S.
|
// map the trapframe just below TRAMPOLINE, for trampoline.S.
|
||||||
mappages(pagetable, TRAPFRAME, PGSIZE,
|
if(mappages(pagetable, TRAPFRAME, PGSIZE,
|
||||||
(uint64)(p->trapframe), PTE_R | PTE_W);
|
(uint64)(p->trapframe), PTE_R | PTE_W) < 0){
|
||||||
|
uvmunmap(pagetable, TRAMPOLINE, 1, 0);
|
||||||
|
uvmfree(pagetable, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return pagetable;
|
return pagetable;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue