A block allocator for userspace wq work

上级 c409bcd3
......@@ -32,14 +32,16 @@ struct cwork : public work {
#include <stdlib.h>
#include <assert.h>
#include <atomic>
#define xmalloc(n) malloc(n)
#define xfree(p, sz) free(p)
#define xallocwork(n) malloc(n)
#define xfreework(p, sz) free(p)
#elif defined(XV6_KERNEL)
#define xmalloc(n) kmalloc(n, "xmalloc")
#define xfree(p, sz) kmfree(p, sz)
#define xallocwork(n) kmalloc(n, "xallocwork")
#define xfreework(p, sz) kmfree(p, sz)
#else
#define xmalloc(n) malloc(n)
#define xfree(p, sz) free(p)
extern void* allocwork(unsigned long nbytes);
extern void freework(void *ptr);
#define xallocwork(n) allocwork(n)
#define xfreework(n, sz) freework(n)
#endif
#include "wqfor.hh"
......@@ -28,11 +28,11 @@ struct forwork : public work {
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(forwork<IT, BODY>));
return xmalloc(sizeof(forwork));
return xallocwork(sizeof(forwork));
}
static void operator delete(void*p) {
xfree(p, sizeof(forwork));
xfreework(p, sizeof(forwork));
}
IT &it_;
......
......@@ -2,7 +2,7 @@ $(O)/lib/%.o: CFLAGS:=$(CFLAGS) -DXV6_USER
$(O)/lib/%.o: CXXFLAGS:=$(CXXFLAGS) -DXV6_USER
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o \
threads.o crt.o wq.o perf.o
threads.o crt.o wq.o perf.o wqalloc.o
ULIB := $(addprefix $(O)/lib/, $(ULIB))
.PRECIOUS: $(O)/lib/%.o
......
......@@ -247,7 +247,7 @@ void*
cwork::operator new(unsigned long nbytes)
{
assert(nbytes == sizeof(cwork));
return xmalloc(sizeof(cwork));
return xallocwork(sizeof(cwork));
}
void*
......@@ -260,5 +260,5 @@ cwork::operator new(unsigned long nbytes, cwork* buf)
void
cwork::operator delete(void *p)
{
xfree(p, sizeof(cwork));
xfreework(p, sizeof(cwork));
}
#include "types.h"
#include "stat.h"
#include "user.h"
#include "lib.h"
#include "percpu.hh"
#define WQCHUNKSZ 8192
#define WQBLOCKSZ 128
static_assert(WQCHUNKSZ%WQBLOCKSZ == 0, "Bad sizes");
struct wqblock {
wqblock* next;
};
percpu<wqblock*> block;
static bool
refill(void)
{
long r = map(0, WQCHUNKSZ);
if (r < 0)
return false;
for (uptr p = r; p < r+WQCHUNKSZ; p += WQBLOCKSZ) {
wqblock* n = (wqblock*)p;
n->next = *block;
*block = n;
}
return true;
}
void*
allocwork(unsigned long nbytes)
{
assert(nbytes <= WQBLOCKSZ);
if (*block == nullptr)
if (!refill())
return nullptr;
wqblock *r = *block;
*block = r->next;
return r;
}
void
freework(void *ptr)
{
wqblock* b = (wqblock*) ptr;
b->next = *block;
*block = b;
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论