提交 731728ab 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

atomic (lockless) kmalloc

上级 4646ef72
...@@ -19,9 +19,8 @@ struct header { ...@@ -19,9 +19,8 @@ struct header {
}; };
struct freelist { struct freelist {
struct header *buckets[KMMAX+1]; std::atomic<header*> buckets[KMMAX+1];
char name[MAXNAME]; char name[MAXNAME];
struct spinlock lock;
}; };
struct freelist freelists[NCPU]; struct freelist freelists[NCPU];
...@@ -32,17 +31,16 @@ kminit(void) ...@@ -32,17 +31,16 @@ kminit(void)
for (int c = 0; c < NCPU; c++) { for (int c = 0; c < NCPU; c++) {
freelists[c].name[0] = (char) c + '0'; freelists[c].name[0] = (char) c + '0';
safestrcpy(freelists[c].name+1, "freelist", MAXNAME-1); safestrcpy(freelists[c].name+1, "freelist", MAXNAME-1);
initlock(&freelists[c].lock, freelists[c].name, LOCKSTAT_KMALLOC);
} }
} }
// get more space for freelists[c].buckets[b] // get more space for freelists[c].buckets[b]
void int
morecore(int c, int b) morecore(int c, int b)
{ {
char *p = kalloc(); char *p = kalloc();
if(p == 0) if(p == 0)
return; return -1;
int sz = 1 << b; int sz = 1 << b;
for(char *q = p; for(char *q = p;
...@@ -52,15 +50,14 @@ morecore(int c, int b) ...@@ -52,15 +50,14 @@ morecore(int c, int b)
h->next = freelists[c].buckets[b]; h->next = freelists[c].buckets[b];
freelists[c].buckets[b] = h; freelists[c].buckets[b] = h;
} }
return 0;
} }
void * void *
kmalloc(u64 nbytes) kmalloc(u64 nbytes)
{ {
int nn = 1, b = 0; int nn = 1, b = 0;
void *r = 0;
struct header *h;
int c = mycpu()->id;
while(nn < nbytes && b <= KMMAX){ while(nn < nbytes && b <= KMMAX){
nn *= 2; nn *= 2;
...@@ -71,21 +68,27 @@ kmalloc(u64 nbytes) ...@@ -71,21 +68,27 @@ kmalloc(u64 nbytes)
if(b > KMMAX) if(b > KMMAX)
panic("kmalloc too big"); panic("kmalloc too big");
acquire(&freelists[c].lock); scoped_gc_epoch gc;
if(freelists[c].buckets[b] == 0) struct header *h;
morecore(c, b); int c = mycpu()->id;
h = freelists[c].buckets[b];
if(h){ for (;;) {
freelists[c].buckets[b] = h->next; h = freelists[c].buckets[b];
r = h + 1; if (!h) {
h->next = (header*) (long) b; if (morecore(c, b) < 0) {
cprintf("kmalloc(%d) failed\n", (int) nbytes);
return 0;
}
} else {
if (cmpxch(&freelists[c].buckets[b], h, h->next))
break;
}
} }
release(&freelists[c].lock);
if (r) void *r = h + 1;
mtlabel(mtrace_label_heap, r, nbytes, "kmalloc'ed", sizeof("kmalloc'ed")); h->next = (header*) (long) b;
if(r == 0)
cprintf("kmalloc(%d) failed\n", (int) nbytes); mtlabel(mtrace_label_heap, r, nbytes, "kmalloc'ed", sizeof("kmalloc'ed"));
return r; return r;
} }
...@@ -96,8 +99,6 @@ kmfree(void *ap) ...@@ -96,8 +99,6 @@ kmfree(void *ap)
struct header *h; struct header *h;
int b; int b;
acquire(&freelists[c].lock);
h = (struct header *) ((char *)ap - sizeof(struct header)); h = (struct header *) ((char *)ap - sizeof(struct header));
b = (long) h->next; b = (long) h->next;
if(b < 0 || b > KMMAX) if(b < 0 || b > KMMAX)
...@@ -108,9 +109,10 @@ kmfree(void *ap) ...@@ -108,9 +109,10 @@ kmfree(void *ap)
memset(ap, 3, (1<<b) - sizeof(struct header)); memset(ap, 3, (1<<b) - sizeof(struct header));
h->next = freelists[c].buckets[b]; h->next = freelists[c].buckets[b];
freelists[c].buckets[b] = h; while (!cmpxch_update(&freelists[c].buckets[b], &h->next, h))
; /* spin */
mtunlabel(mtrace_label_heap, ap); mtunlabel(mtrace_label_heap, ap);
release(&freelists[c].lock);
} }
int int
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论