提交 a7b311ad 创建 作者: Robert Morris's avatar Robert Morris

separate kmalloc from kalloc

上级 1bb8082e
......@@ -42,6 +42,7 @@ OBJS = \
hwvm.o \
hz.o \
kalloc.o \
kmalloc.o \
kbd.o \
main.o \
memide.o \
......
// Physical memory allocator, intended to allocate
// memory for user processes, kernel stacks, page table pages,
// and pipe buffers. Allocates 4096-byte pages.
//
// Physical page allocator.
// Slab allocator, for chunks larger than one page.
//
#include "types.h"
#include "mmu.h"
......@@ -31,9 +32,9 @@ static struct kmem slabmem[][NCPU] = {
extern char end[]; // first address after kernel loaded from ELF file
char *newend;
enum { kalloc_memset = 1 };
static int kinited __mpalign__;
extern void kminit();
static struct Mbmem *
memsearch(paddr pa)
......@@ -162,7 +163,7 @@ kmemprint(void)
}
static char*
kmemalloc(struct kmem *km)
kalloc_pool(struct kmem *km)
{
struct run *r = 0;
struct kmem *m;
......@@ -201,38 +202,13 @@ kalloc(void)
{
if (!kinited)
return pgalloc();
return kmemalloc(kmems);
return kalloc_pool(kmems);
}
void *
ksalloc(slab_t slab)
{
return kmemalloc(slabmem[slab]);
}
// Memory allocator by Kernighan and Ritchie,
// The C programming Language, 2nd ed. Section 8.7.
typedef struct header {
struct header *ptr;
u64 size; // in multiples of sizeof(Header)
} __mpalign__ Header;
static struct freelist {
Header base;
Header *freep; // last allocated block
struct spinlock lock;
char name[MAXNAME];
} freelists[NCPU];
static void
kminit(void)
{
for (int c = 0; c < NCPU; c++) {
freelists[c].name[0] = (char) c + '0';
safestrcpy(freelists[c].name+1, "freelist", MAXNAME-1);
initlock(&freelists[c].lock, freelists[c].name);
}
return kalloc_pool(slabmem[slab]);
}
void
......@@ -302,99 +278,6 @@ initkalloc(u64 mbaddr)
kinited = 1;
}
static void
domfree(void *ap)
{
Header *bp, *p;
bp = (Header*)ap - 1;
if (kalloc_memset)
memset(ap, 3, (bp->size-1) * sizeof(*bp));
for(p = freelists[mycpu()->id].freep; !(bp > p && bp < p->ptr); p = p->ptr)
if(p >= p->ptr && (bp > p || bp < p->ptr))
break;
if(bp + bp->size == p->ptr){
bp->size += p->ptr->size;
bp->ptr = p->ptr->ptr;
} else
bp->ptr = p->ptr;
if(p + p->size == bp){
p->size += bp->size;
p->ptr = bp->ptr;
} else
p->ptr = bp;
freelists[mycpu()->id].freep = p;
}
void
kmfree(void *ap)
{
acquire(&freelists[mycpu()->id].lock);
domfree(ap);
mtunlabel(mtrace_label_heap, ap);
release(&freelists[mycpu()->id].lock);
}
// Caller should hold free_locky
static Header*
morecore(u64 nu)
{
static u64 units_per_page = PGSIZE / sizeof(Header);
char *p;
Header *hp;
if(nu != units_per_page) {
if (nu > units_per_page)
panic("morecore");
nu = units_per_page; // we allocate nu * sizeof(Header)
}
p = kalloc();
if(p == 0)
return 0;
hp = (Header*)p;
hp->size = nu;
domfree((void*)(hp + 1));
return freelists[mycpu()->id].freep;
}
void*
kmalloc(u64 nbytes)
{
Header *p, *prevp;
u64 nunits;
void *r = 0;
acquire(&freelists[mycpu()->id].lock);
nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
if((prevp = freelists[mycpu()->id].freep) == 0){
freelists[mycpu()->id].base.ptr =
freelists[mycpu()->id].freep = prevp = &freelists[mycpu()->id].base;
freelists[mycpu()->id].base.size = 0;
}
for(p = prevp->ptr; ; prevp = p, p = p->ptr){
if(p->size >= nunits){
if(p->size == nunits)
prevp->ptr = p->ptr;
else {
p->size -= nunits;
p += p->size;
p->size = nunits;
}
freelists[mycpu()->id].freep = prevp;
r = (void*)(p + 1);
break;
}
if(p == freelists[mycpu()->id].freep)
if((p = morecore(nunits)) == 0)
break;
}
release(&freelists[mycpu()->id].lock);
if (r)
mtlabel(mtrace_label_heap, r, nbytes, "kmalloc'ed", sizeof("kmalloc'ed"));
return r;
}
void
kfree(void *v)
{
......@@ -406,19 +289,3 @@ ksfree(slab_t slab, void *v)
{
kfree_pool(slabmem[slab], v);
}
int
kmalign(void **p, int align, u64 size)
{
void *mem = kmalloc(size + (align-1) + sizeof(void*));
char *amem = ((char*)mem) + sizeof(void*);
amem += align - ((uptr)amem & (align - 1));
((void**)amem)[-1] = mem;
*p = amem;
return 0;
}
void kmalignfree(void *mem)
{
kmfree(((void**)mem)[-1]);
}
......@@ -12,3 +12,5 @@ struct kmem {
} __mpalign__;
extern struct kmem kmems[NCPU];
enum { kalloc_memset = 1 };
//
// Allocate objects smaller than a page.
//
#include "types.h"
#include "mmu.h"
#include "kernel.h"
#include "spinlock.h"
#include "kalloc.h"
#include "mtrace.h"
#include "cpu.h"
// Memory allocator by Kernighan and Ritchie,
// The C programming Language, 2nd ed. Section 8.7.
typedef struct header {
struct header *ptr;
u64 size; // in multiples of sizeof(Header)
} __mpalign__ Header;
static struct freelist {
Header base;
Header *freep; // last allocated block
struct spinlock lock;
char name[MAXNAME];
} freelists[NCPU];
void
kminit(void)
{
for (int c = 0; c < NCPU; c++) {
freelists[c].name[0] = (char) c + '0';
safestrcpy(freelists[c].name+1, "freelist", MAXNAME-1);
initlock(&freelists[c].lock, freelists[c].name);
}
}
static void
domfree(void *ap)
{
Header *bp, *p;
bp = (Header*)ap - 1;
if (kalloc_memset)
memset(ap, 3, (bp->size-1) * sizeof(*bp));
for(p = freelists[mycpu()->id].freep; !(bp > p && bp < p->ptr); p = p->ptr)
if(p >= p->ptr && (bp > p || bp < p->ptr))
break;
if(bp + bp->size == p->ptr){
bp->size += p->ptr->size;
bp->ptr = p->ptr->ptr;
} else
bp->ptr = p->ptr;
if(p + p->size == bp){
p->size += bp->size;
p->ptr = bp->ptr;
} else
p->ptr = bp;
freelists[mycpu()->id].freep = p;
}
void
kmfree(void *ap)
{
acquire(&freelists[mycpu()->id].lock);
domfree(ap);
mtunlabel(mtrace_label_heap, ap);
release(&freelists[mycpu()->id].lock);
}
// Caller should hold free_lock
static Header*
morecore(u64 nu)
{
static u64 units_per_page = PGSIZE / sizeof(Header);
char *p;
Header *hp;
if(nu != units_per_page) {
if (nu > units_per_page)
panic("morecore");
nu = units_per_page; // we allocate nu * sizeof(Header)
}
p = kalloc();
if(p == 0)
return 0;
hp = (Header*)p;
hp->size = nu;
domfree((void*)(hp + 1));
return freelists[mycpu()->id].freep;
}
void*
kmalloc(u64 nbytes)
{
Header *p, *prevp;
u64 nunits;
void *r = 0;
acquire(&freelists[mycpu()->id].lock);
nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1;
if((prevp = freelists[mycpu()->id].freep) == 0){
freelists[mycpu()->id].base.ptr =
freelists[mycpu()->id].freep = prevp = &freelists[mycpu()->id].base;
freelists[mycpu()->id].base.size = 0;
}
for(p = prevp->ptr; ; prevp = p, p = p->ptr){
if(p->size >= nunits){
if(p->size == nunits)
prevp->ptr = p->ptr;
else {
p->size -= nunits;
p += p->size;
p->size = nunits;
}
freelists[mycpu()->id].freep = prevp;
r = (void*)(p + 1);
break;
}
if(p == freelists[mycpu()->id].freep)
if((p = morecore(nunits)) == 0)
break;
}
release(&freelists[mycpu()->id].lock);
if (r)
mtlabel(mtrace_label_heap, r, nbytes, "kmalloc'ed", sizeof("kmalloc'ed"));
return r;
}
int
kmalign(void **p, int align, u64 size)
{
void *mem = kmalloc(size + (align-1) + sizeof(void*));
char *amem = ((char*)mem) + sizeof(void*);
amem += align - ((uptr)amem & (align - 1));
((void**)amem)[-1] = mem;
*p = amem;
return 0;
}
void kmalignfree(void *mem)
{
kmfree(((void**)mem)[-1]);
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论