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

use versioned ptrs to avoid aba in kmalloc too

上级 883a02e7
...@@ -19,7 +19,7 @@ struct header { ...@@ -19,7 +19,7 @@ struct header {
}; };
struct freelist { struct freelist {
std::atomic<header*> buckets[KMMAX+1]; versioned<header*> buckets[KMMAX+1];
char name[MAXNAME]; char name[MAXNAME];
}; };
...@@ -46,9 +46,12 @@ morecore(int c, int b) ...@@ -46,9 +46,12 @@ morecore(int c, int b)
assert(sz >= sizeof(header)); assert(sz >= sizeof(header));
for(char *q = p; q + sz <= p + PGSIZE; q += sz){ for(char *q = p; q + sz <= p + PGSIZE; q += sz){
struct header *h = (struct header *) q; struct header *h = (struct header *) q;
h->next = freelists[c].buckets[b]; for (;;) {
while (!cmpxch_update(&freelists[c].buckets[b], &h->next, h)) auto headptr = freelists[c].buckets[b].load();
; /* spin */ h->next = headptr.ptr();
if (freelists[c].buckets[b].compare_exchange(headptr, h))
break;
}
} }
return 0; return 0;
...@@ -81,7 +84,8 @@ kmalloc(u64 nbytes) ...@@ -81,7 +84,8 @@ kmalloc(u64 nbytes)
int c = mycpu()->id; int c = mycpu()->id;
for (;;) { for (;;) {
h = freelists[c].buckets[b]; auto headptr = freelists[c].buckets[b].load();
h = headptr.ptr();
if (!h) { if (!h) {
if (morecore(c, b) < 0) { if (morecore(c, b) < 0) {
cprintf("kmalloc(%d) failed\n", (int) nbytes); cprintf("kmalloc(%d) failed\n", (int) nbytes);
...@@ -89,7 +93,7 @@ kmalloc(u64 nbytes) ...@@ -89,7 +93,7 @@ kmalloc(u64 nbytes)
} }
} else { } else {
header *nxt = h->next; header *nxt = h->next;
if (cmpxch(&freelists[c].buckets[b], h, nxt)) { if (freelists[c].buckets[b].compare_exchange(headptr, nxt)) {
if (h->next != nxt) if (h->next != nxt)
panic("kmalloc: aba race"); panic("kmalloc: aba race");
break; break;
...@@ -117,9 +121,12 @@ kmfree(void *ap, u64 nbytes) ...@@ -117,9 +121,12 @@ kmfree(void *ap, u64 nbytes)
memset(ap, 3, (1<<b)); memset(ap, 3, (1<<b));
int c = mycpu()->id; int c = mycpu()->id;
h->next = freelists[c].buckets[b]; for (;;) {
while (!cmpxch_update(&freelists[c].buckets[b], &h->next, h)) auto headptr = freelists[c].buckets[b].load();
; /* spin */ h->next = headptr.ptr();
if (freelists[c].buckets[b].compare_exchange(headptr, h))
break;
}
mtunlabel(mtrace_label_heap, ap); mtunlabel(mtrace_label_heap, ap);
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论