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

kmalloc/kmfree

dynamically allocate struct procs
上级 f2b96eaa
......@@ -67,9 +67,13 @@ extern uchar ioapicid;
void ioapicinit(void);
// kalloc.c
void kinit(void);
char* kalloc(void);
void kfree(char*);
void kinit(void);
void* kmalloc(uint);
void kmfree(void*);
// kbd.c
void kbdintr(void);
......
......@@ -16,6 +16,7 @@
struct kmem kmems[NCPU];
extern char end[]; // first address after kernel loaded from ELF file
struct spinlock free_lock;
static void __attribute__((unused))
kmemprint(void)
......@@ -44,6 +45,8 @@ kinit(void)
p = (char*)PGROUNDUP((uint)end);
for(; p + PGSIZE <= (char*)PHYSTOP; p += PGSIZE)
kfree(p);
initlock(&free_lock, "malloc");
}
//PAGEBREAK: 21
......@@ -117,3 +120,106 @@ kalloc(void)
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)
struct proc *p;
char *sp;
#if 0
acquire(&ptable->lock);
for(p = ptable->proc; p < &ptable->proc[NPROC]; p++)
if(p->state == UNUSED)
goto found;
release(&ptable->lock);
return 0;
found:
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->cpuid = cpu->id;
p->curcycles = 0;
release(&ptable->lock);
// Allocate kernel stack if possible.
if((p->kstack = kalloc()) == 0){
......@@ -110,7 +119,7 @@ void
addrun(struct proc *p)
{
acquire(&runqs[p->cpuid].lock);
// cprintf("%d: addrun %d\n", cpunum(), p->pid);
// cprintf("%d: addrun %d\n", cpunum(), p->pid);
addrun1(&runqs[p->cpuid], p);
release(&runqs[p->cpuid].lock);
}
......@@ -148,6 +157,7 @@ userinit(void)
extern char _binary_initcode_start[], _binary_initcode_size[];
p = allocproc();
cprintf("allocproc -> 0x%x\n", p);
initproc = p;
if((p->vmap = vmap_alloc()) == 0)
panic("userinit: out of vmaps?");
......@@ -277,6 +287,7 @@ fork(int flags)
kfree(np->kstack);
np->kstack = 0;
np->state = UNUSED;
kmfree(np);
return -1;
}
} else {
......@@ -388,6 +399,7 @@ wait(void)
p->killed = 0;
release(&p->lock);
release(&proc->lock);
kmfree(p);
return pid;
}
release(&p->lock);
......@@ -416,7 +428,7 @@ migrate(void)
if (c == cpunum())
continue;
if (idle[c]) { // OK if there is a race
cprintf("migrate to %d\n", c);
// cprintf("migrate to %d\n", c);
p = proc;
p->curcycles = 0;
p->cpuid = c;
......
......@@ -363,7 +363,7 @@ vmap_alloc(void)
return m;
}
}
panic("out of vmaps");
return 0;
}
static void
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论