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

switch bio to use the c++ namespace impl

上级 59d5a46b
...@@ -29,31 +29,18 @@ extern "C" { ...@@ -29,31 +29,18 @@ extern "C" {
#include "buf.h" #include "buf.h"
} }
static struct ns *bufns; #include "cpputil.hh"
#include "ns.hh"
enum { writeback = 0 }; u64
bio_hash(const pair<u32, u64> &p)
static void *
evict(void *vkey, void *bp, void *arg)
{ {
struct buf *b = (buf*) bp; return p._a ^ p._b;
acquire(&b->lock);
if ((b->flags & (B_BUSY | B_DIRTY | B_VALID)) == 0)
return b;
release(&b->lock);
return 0;
} }
static void * static xns<pair<u32, u64>, buf*, bio_hash> *bufns;
evict_valid(void *vkey, void *bp, void *arg)
{ enum { writeback = 0 };
struct buf *b = (buf*) bp;
acquire(&b->lock);
if ((b->flags & (B_BUSY | B_DIRTY)) == 0)
return b;
release(&b->lock);
return 0;
}
// Look through buffer cache for sector on device dev. // Look through buffer cache for sector on device dev.
// If not found, allocate fresh block. // If not found, allocate fresh block.
...@@ -67,7 +54,7 @@ bget(u32 dev, u64 sector, int *writer) ...@@ -67,7 +54,7 @@ bget(u32 dev, u64 sector, int *writer)
// Try for cached block. // Try for cached block.
// XXX ignore dev // XXX ignore dev
gc_begin_epoch(); gc_begin_epoch();
b = (buf*) ns_lookup(bufns, KII(dev, sector)); b = bufns->lookup(mkpair(dev, sector));
if (b) { if (b) {
if (b->dev != dev || b->sector != sector) if (b->dev != dev || b->sector != sector)
panic("block mismatch"); panic("block mismatch");
...@@ -91,13 +78,30 @@ bget(u32 dev, u64 sector, int *writer) ...@@ -91,13 +78,30 @@ bget(u32 dev, u64 sector, int *writer)
gc_end_epoch(); gc_end_epoch();
// Allocate fresh block. // Allocate fresh block.
struct buf *victim = (buf*) ns_enumerate(bufns, evict, 0); struct buf *victim = 0;
bufns->enumerate([&victim](const pair<u32, u64>&, buf *b) {
acquire(&b->lock);
if ((b->flags & (B_BUSY | B_DIRTY | B_VALID)) == 0) {
victim = b;
return true;
}
release(&b->lock);
return false;
});
if (victim == 0) if (victim == 0)
victim = (buf*) ns_enumerate(bufns, evict_valid, 0); bufns->enumerate([&victim](const pair<u32, u64>&, buf *b) {
acquire(&b->lock);
if ((b->flags & (B_BUSY | B_DIRTY)) == 0) {
victim = b;
return true;
}
release(&b->lock);
return false;
});
if (victim == 0) if (victim == 0)
panic("bget all busy"); panic("bget all busy");
victim->flags |= B_BUSY; victim->flags |= B_BUSY;
ns_remove(bufns, KII(victim->dev, victim->sector), victim); bufns->remove(mkpair(victim->dev, victim->sector), &victim);
release(&victim->lock); release(&victim->lock);
destroylock(&victim->lock); destroylock(&victim->lock);
gc_delayed(victim, kmfree); gc_delayed(victim, kmfree);
...@@ -111,7 +115,7 @@ bget(u32 dev, u64 sector, int *writer) ...@@ -111,7 +115,7 @@ bget(u32 dev, u64 sector, int *writer)
initlock(&b->lock, b->lockname+3, LOCKSTAT_BIO); initlock(&b->lock, b->lockname+3, LOCKSTAT_BIO);
initcondvar(&b->cv, b->lockname); initcondvar(&b->cv, b->lockname);
gc_begin_epoch(); gc_begin_epoch();
if (ns_insert(bufns, KII(b->dev, b->sector), b) < 0) { if (bufns->insert(mkpair(b->dev, b->sector), b) < 0) {
destroylock(&b->lock); destroylock(&b->lock);
gc_delayed(b, kmfree); gc_delayed(b, kmfree);
goto loop; goto loop;
...@@ -165,7 +169,7 @@ brelse(struct buf *b, int writer) ...@@ -165,7 +169,7 @@ brelse(struct buf *b, int writer)
void void
initbio(void) initbio(void)
{ {
bufns = nsalloc(0); bufns = new xns<pair<u32, u64>, buf*, bio_hash>(false);
for (u64 i = 0; i < NBUF; i++) { for (u64 i = 0; i < NBUF; i++) {
struct buf *b = (buf*) kmalloc(sizeof(*b)); struct buf *b = (buf*) kmalloc(sizeof(*b));
...@@ -174,7 +178,7 @@ initbio(void) ...@@ -174,7 +178,7 @@ initbio(void)
b->flags = 0; b->flags = 0;
initlock(&b->lock, "bcache-lock", LOCKSTAT_BIO); initlock(&b->lock, "bcache-lock", LOCKSTAT_BIO);
initcondvar(&b->cv, "bcache-cv"); initcondvar(&b->cv, "bcache-cv");
if (ns_insert(bufns, KII(b->dev, b->sector), b) < 0) if (bufns->insert(mkpair(b->dev, b->sector), b) < 0)
panic("binit ns_insert"); panic("binit ns_insert");
} }
} }
#pragma once
template<class A, class B>
class pair {
public:
A _a;
B _b;
pair(const A &a, const B &b) : _a(a), _b(b) {}
bool operator==(const pair<A, B> &other) {
return _a == other._a && _b == other._b;
}
};
template<class A, class B>
pair<A, B>
mkpair(const A &a, const B &b)
{
return pair<A, B>(a, b);
}
...@@ -11,7 +11,8 @@ extern "C" { ...@@ -11,7 +11,8 @@ extern "C" {
} }
#include "ns.hh" #include "ns.hh"
extern xns<u32, proc*> *xnspid; extern u64 proc_hash(const u32&);
extern xns<u32, proc*, proc_hash> *xnspid;
// GC scheme based on Fraser's: // GC scheme based on Fraser's:
// a machine has a global_epoch // a machine has a global_epoch
......
...@@ -34,7 +34,7 @@ struct xbucket { ...@@ -34,7 +34,7 @@ struct xbucket {
xelem<K, V> * volatile chain; xelem<K, V> * volatile chain;
} __attribute__((aligned (CACHELINE))); } __attribute__((aligned (CACHELINE)));
template<class K, class V> template<class K, class V, u64 (*HF)(const K&)>
class xns { class xns {
private: private:
bool allowdup; bool allowdup;
...@@ -60,7 +60,7 @@ class xns { ...@@ -60,7 +60,7 @@ class xns {
} }
u64 h(const K &key) { u64 h(const K &key) {
return key % NHASH; return HF(key) % NHASH;
} }
int insert(const K &key, const V &val) { int insert(const K &key, const V &val) {
......
...@@ -16,8 +16,14 @@ extern "C" { ...@@ -16,8 +16,14 @@ extern "C" {
#include "ns.hh" #include "ns.hh"
u64
proc_hash(const u32 &p)
{
return p;
}
int __mpalign__ idle[NCPU]; int __mpalign__ idle[NCPU];
xns<u32, proc*> *xnspid __mpalign__; xns<u32, proc*, proc_hash> *xnspid __mpalign__;
static struct proc *bootproc __mpalign__; static struct proc *bootproc __mpalign__;
#if MTRACE #if MTRACE
...@@ -284,7 +290,7 @@ initproc(void) ...@@ -284,7 +290,7 @@ initproc(void)
{ {
int c; int c;
xnspid = new xns<u32, proc*>(false); xnspid = new xns<u32, proc*, proc_hash>(false);
if (xnspid == 0) if (xnspid == 0)
panic("pinit"); panic("pinit");
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论