提交 95e3785c 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

kmalloc/kmfree

dynamically allocate struct procs
上级 f2b96eaa
...@@ -67,9 +67,13 @@ extern uchar ioapicid; ...@@ -67,9 +67,13 @@ extern uchar ioapicid;
void ioapicinit(void); void ioapicinit(void);
// kalloc.c // kalloc.c
void kinit(void);
char* kalloc(void); char* kalloc(void);
void kfree(char*); void kfree(char*);
void kinit(void); void* kmalloc(uint);
void kmfree(void*);
// kbd.c // kbd.c
void kbdintr(void); void kbdintr(void);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
struct kmem kmems[NCPU]; struct kmem kmems[NCPU];
extern char end[]; // first address after kernel loaded from ELF file extern char end[]; // first address after kernel loaded from ELF file
struct spinlock free_lock;
static void __attribute__((unused)) static void __attribute__((unused))
kmemprint(void) kmemprint(void)
...@@ -44,6 +45,8 @@ kinit(void) ...@@ -44,6 +45,8 @@ kinit(void)
p = (char*)PGROUNDUP((uint)end); p = (char*)PGROUNDUP((uint)end);
for(; p + PGSIZE <= (char*)PHYSTOP; p += PGSIZE) for(; p + PGSIZE <= (char*)PHYSTOP; p += PGSIZE)
kfree(p); kfree(p);
initlock(&free_lock, "malloc");
} }
//PAGEBREAK: 21 //PAGEBREAK: 21
...@@ -117,3 +120,106 @@ kalloc(void) ...@@ -117,3 +120,106 @@ kalloc(void)
return (char*)r; return (char*)r;
} }
// Memory allocator by Kernighan and Ritchie,
// The C programming Language, 2nd ed. Section 8.7.
typedef long Align;
union header {
struct {
union header *ptr;
uint size; // in multiples of sizeof(Header)
} s;
Align x;
};
typedef union header Header;
static Header base;
static Header *freep; // last allocated block
static void
domfree(void *ap)
{
Header *bp, *p;
bp = (Header*)ap - 1;
for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
if(p >= p->s.ptr && (bp > p || bp < p->s.ptr))
break;
if(bp + bp->s.size == p->s.ptr){
bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
} else
bp->s.ptr = p->s.ptr;
if(p + p->s.size == bp){
p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
} else
p->s.ptr = bp;
freep = p;
}
void
kmfree(void *ap)
{
acquire(&free_lock);
domfree(ap);
release(&free_lock);
}
// Caller should hold free_locky
static Header*
morecore(uint nu)
{
char *p;
Header *hp;
if(nu != 512) {
if (nu > 512)
panic("morecore");
nu = 512; // we allocate nu * sizeof(Header)
}
p = kalloc();
if(p == (char*)-1)
return 0;
hp = (Header*)p;
hp->s.size = nu;
domfree((void*)(hp + 1));
return freep;
}
void*
kmalloc(uint nbytes)
{
Header *p, *prevp;
uint nunits;
void *r = 0;
acquire(&free_lock);
nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
if((prevp = freep) == 0){
base.s.ptr = freep = prevp = &base;
base.s.size = 0;
}
for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){
if(p->s.size >= nunits){
if(p->s.size == nunits)
prevp->s.ptr = p->s.ptr;
else {
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
r = (void*)(p + 1);
break;
}
if(p == freep)
if((p = morecore(nunits)) == 0)
break;
}
release(&free_lock);
return r;
}
...@@ -55,19 +55,28 @@ allocproc(void) ...@@ -55,19 +55,28 @@ allocproc(void)
struct proc *p; struct proc *p;
char *sp; char *sp;
#if 0
acquire(&ptable->lock); acquire(&ptable->lock);
for(p = ptable->proc; p < &ptable->proc[NPROC]; p++) for(p = ptable->proc; p < &ptable->proc[NPROC]; p++)
if(p->state == UNUSED) if(p->state == UNUSED)
goto found; goto found;
release(&ptable->lock); release(&ptable->lock);
return 0; return 0;
found: found:
p->state = EMBRYO; p->state = EMBRYO;
release(&ptable->lock);
#else
p = kmalloc(sizeof(struct proc));
if (p == 0) return 0;
memset(p, 0, sizeof(*p));
p->state = EMBRYO;
initlock(&p->lock, "proc");
initcondvar(&p->cv, "proc");
#endif
p->state = EMBRYO;
p->pid = ptable->nextpid++; p->pid = ptable->nextpid++;
p->cpuid = cpu->id; p->cpuid = cpu->id;
p->curcycles = 0;
release(&ptable->lock);
// Allocate kernel stack if possible. // Allocate kernel stack if possible.
if((p->kstack = kalloc()) == 0){ if((p->kstack = kalloc()) == 0){
...@@ -148,6 +157,7 @@ userinit(void) ...@@ -148,6 +157,7 @@ userinit(void)
extern char _binary_initcode_start[], _binary_initcode_size[]; extern char _binary_initcode_start[], _binary_initcode_size[];
p = allocproc(); p = allocproc();
cprintf("allocproc -> 0x%x\n", p);
initproc = p; initproc = p;
if((p->vmap = vmap_alloc()) == 0) if((p->vmap = vmap_alloc()) == 0)
panic("userinit: out of vmaps?"); panic("userinit: out of vmaps?");
...@@ -277,6 +287,7 @@ fork(int flags) ...@@ -277,6 +287,7 @@ fork(int flags)
kfree(np->kstack); kfree(np->kstack);
np->kstack = 0; np->kstack = 0;
np->state = UNUSED; np->state = UNUSED;
kmfree(np);
return -1; return -1;
} }
} else { } else {
...@@ -388,6 +399,7 @@ wait(void) ...@@ -388,6 +399,7 @@ wait(void)
p->killed = 0; p->killed = 0;
release(&p->lock); release(&p->lock);
release(&proc->lock); release(&proc->lock);
kmfree(p);
return pid; return pid;
} }
release(&p->lock); release(&p->lock);
...@@ -416,7 +428,7 @@ migrate(void) ...@@ -416,7 +428,7 @@ migrate(void)
if (c == cpunum()) if (c == cpunum())
continue; continue;
if (idle[c]) { // OK if there is a race if (idle[c]) { // OK if there is a race
cprintf("migrate to %d\n", c); // cprintf("migrate to %d\n", c);
p = proc; p = proc;
p->curcycles = 0; p->curcycles = 0;
p->cpuid = c; p->cpuid = c;
......
...@@ -363,7 +363,7 @@ vmap_alloc(void) ...@@ -363,7 +363,7 @@ vmap_alloc(void)
return m; return m;
} }
} }
panic("out of vmaps"); return 0;
} }
static void static void
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论