Try pre-zeroing with wqs

上级 f71b44c4
...@@ -22,6 +22,7 @@ void initnmi(void); ...@@ -22,6 +22,7 @@ void initnmi(void);
void inittrap(void); void inittrap(void);
void initseg(void); void initseg(void);
void initkalloc(u64 mbaddr); void initkalloc(u64 mbaddr);
void initz(void);
void initrcu(void); void initrcu(void);
void initproc(void); void initproc(void);
void initbio(void); void initbio(void);
...@@ -107,6 +108,7 @@ cmain(u64 mbmagic, u64 mbaddr) ...@@ -107,6 +108,7 @@ cmain(u64 mbmagic, u64 mbaddr)
inittrap(); inittrap();
initlapic(); initlapic();
initkalloc(mbaddr); initkalloc(mbaddr);
initz();
initproc(); // process table initproc(); // process table
initsched(); // scheduler run queues initsched(); // scheduler run queues
initidle(); initidle();
......
...@@ -48,10 +48,17 @@ __fetch_end: ...@@ -48,10 +48,17 @@ __fetch_end:
movl $0, PROC_UACCESS(%r11) movl $0, PROC_UACCESS(%r11)
ret ret
.globl clear_page .globl zpage
.align 8 .align 8
clear_page: zpage:
movl $4096/8,%ecx movl $4096/8,%ecx
xorl %eax,%eax xorl %eax,%eax
rep stosq rep stosq
ret ret
// XXX(sbw) should skip first cache line, prefetchnt, then zero
.globl zrun_nc
.align 8
zrun_nc:
jmp zpage
\ No newline at end of file
...@@ -4,34 +4,110 @@ ...@@ -4,34 +4,110 @@
#include "percpu.hh" #include "percpu.hh"
#include "wq.hh" #include "wq.hh"
#include "kalloc.hh" #include "kalloc.hh"
#include "cpputil.hh"
extern "C" void clear_page(void*); extern "C" void zpage(void*);
extern "C" void zrun_nc(run*);
struct zallocator { struct zallocator {
run* run; run* run;
kmem kmem;
wframe frame; wframe frame;
};
void init(int);
char* alloc(const char*);
void free(char*);
void tryrefill();
};
percpu<zallocator> z_; percpu<zallocator> z_;
struct zwork : public work {
zwork(wframe* frame, zallocator* zer)
: frame_(frame), zer_(zer)
{
frame_->inc();
}
virtual void run() {
for (int i = 0; i < 32; i++) {
struct run* r = (struct run*)kalloc("zpage");
if (r == nullptr)
break;
zrun_nc(r);
zer_->kmem.free(r);
}
frame_->dec();
delete this;
}
wframe* frame_;
zallocator* zer_;
NEW_DELETE_OPS(zwork);
};
//
// zallocator
//
void
zallocator::tryrefill(void)
{
if (kmem.nfree < 16 && frame.zero()) {
zwork* w = new zwork(&frame, this);
if (wq_push(w) < 0)
delete w;
}
}
void
zallocator::init(int c)
{
frame.clear();
kmem.name[0] = (char) c + '0';
safestrcpy(kmem.name+1, "zmem", MAXNAME-1);
kmem.size = PGSIZE;
}
char* char*
zalloc(const char* name) zallocator::alloc(const char* name)
{ {
char* p = kalloc(name); char* p;
if (p)
clear_page(p); p = (char*) kmem.alloc(name);
if (p == nullptr) {
p = kalloc(name);
if (p != nullptr)
zpage(p);
}
tryrefill();
return p; return p;
} }
void void
zallocator::free(char* p)
{
if (0)
for (int i = 0; i < 4096; i++)
assert(p[i] == 0);
kmem.free((struct run*)p);
}
char*
zalloc(const char* name)
{
return z_->alloc(name);
}
void
zfree(char* p) zfree(char* p)
{ {
kfree(p); z_->free(p);
} }
void void
initz(void) initz(void)
{ {
for (int i = 0; i < NCPU; i++) for (int c = 0; c < NCPU; c++)
z_[i].frame.clear(); z_[c].init(c);
} }
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论