提交 84865c8b 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

Merge branch 'scale-amd64' of ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale-amd64

......@@ -42,6 +42,10 @@ public:
// XXX(sbw) if f->ref_ > 1 the kernel will not actually close
// the file when this function returns (i.e. sys_close can return
// while the file/pipe/socket is still open).
if (fd >= NOFILE) {
cprintf("filetable::close: bad fd %u\n", fd);
return;
}
file* f = ofile_[fd].exchange(nullptr);
if (f != nullptr)
......
......@@ -25,10 +25,16 @@ class markptr {
markptr_ptr<T>& ptr() {
return *(markptr_ptr<T>*) this;
}
const markptr_ptr<T>& ptr() const {
return *(const markptr_ptr<T>*) this;
}
markptr_mark<T>& mark() {
return *(markptr_mark<T>*) this;
}
const markptr_mark<T>& mark() const {
return *(const markptr_mark<T>*) this;
}
// Convenience operator to avoid having to write out xx.ptr()->...
T* operator->() { return ptr(); }
......
......@@ -78,6 +78,39 @@ struct radix_iterator {
return r_ != other.r_ || k_ != other.k_; }
};
struct radix_iterator2 {
const radix* r_;
u64 k_;
// path_[i] is the node at level i. Note that the leaf is at zero
// and is radix_elem. The rest are radix_node. For now we assume all
// leaves are at level 0. Later we'll steal a bit for them. The root
// is path_[radix_levels].
void *path_[radix_levels+1];
radix_iterator2(const radix* r, u64 k);
radix_iterator2 &operator++() {
if (!advance(radix_levels-1)) k_ = ~0ULL;
return *this;
}
radix_elem* operator*() {
return (radix_elem*)path_[0];
}
radix_node* node(u32 level) { return (radix_node*)path_[level]; }
// Compare equality on just the key.
bool operator==(const radix_iterator2 &other) {
return r_ == other.r_ && k_ == other.k_; }
bool operator!=(const radix_iterator2 &other) {
return r_ != other.r_ || k_ != other.k_; }
private:
bool find_first_leaf(u32 level);
bool advance(u32 level);
};
#define radix_iterator radix_iterator2
static inline radix_iterator
begin(const radix &r) { return radix_iterator(&r, 0); }
......@@ -91,3 +124,4 @@ begin(const radix_range &rr) { return radix_iterator(rr.r_, rr.start_); }
static inline radix_iterator
end(const radix_range &rr) { return radix_iterator(rr.r_, rr.start_ + rr.size_); }
#undef radix_iterator
......@@ -93,12 +93,10 @@ idleloop(void)
mtstart(idleloop, myproc());
sti();
sampidle(true);
for (;;) {
acquire(&myproc()->lock);
myproc()->set_state(RUNNABLE);
sched();
sampidle(true);
finishzombies();
......
#include "crange_arch.hh"
#include "radix.hh"
enum { crange_debug = 0 };
#define dprintf(...) do { if (crange_debug) cprintf(__VA_ARGS__); } while(0)
// Returns the index needed to reach |level| from |level+1|.
static u32
index(u64 key, u32 level)
{
u64 idx = key >> (bits_per_level * level);
idx &= (1 << bits_per_level) - 1;
return idx;
}
// Returns the level we stopped at.
template<class CB>
u32
......@@ -25,9 +38,7 @@ descend(u64 key, markptr<void> *n, u32 level, CB cb, bool create)
radix_node *rn = (radix_node*) v;
u64 idx = key >> (bits_per_level * level);
idx &= (1<<bits_per_level)-1;
markptr<void> *vptr = &rn->ptr[idx];
markptr<void> *vptr = &rn->ptr[index(key, level)];
if (level == 0) {
cb(vptr);
return level;
......@@ -43,6 +54,7 @@ radix::search(u64 key)
descend(key >> shift_, &root_, radix_levels-1, [&result](markptr<void> *v) {
result = (radix_elem*) v->ptr().load();
}, false);
dprintf("%p: search(%lu) -> %p\n", this, key >> shift_, result);
return result;
}
......@@ -104,6 +116,7 @@ radix_range::replace(u64 start, u64 size, radix_elem *val)
{
start = start >> r_->shift_;
size = size >> r_->shift_;
dprintf("%p: replace: [%lu, %lu) with %p\n", r_, start, start + size, val);
assert(start >= start_);
assert(start + size <= start_ + size_);
......@@ -132,3 +145,59 @@ radix_iterator::operator*()
}, false);
return result;
}
radix_iterator2::radix_iterator2(const radix* r, u64 k)
: r_(r), k_(k) {
dprintf("%p: Made iterator with k = %lu\n", r_, k_);
if (k_ != ~0ULL) {
path_[radix_levels] = r_->root_.ptr().load();
if (!find_first_leaf(radix_levels - 1))
k_ = ~0ULL;
}
dprintf("%p: Adjusted: k = %lu\n", r_, k_);
}
bool
radix_iterator2::advance(u32 level)
{
// First, see if we can advance a lower level.
if (level > 0 && advance(level-1)) {
// Nothing more to do.
return true;
}
// Try to advance this level, if we can.
u32 start_idx = index(k_, level)+1;
if (start_idx < (1<<bits_per_level)) {
// Find the first leaf starting at our sibling node.
k_ &= ~((1ULL<<((level+1) * bits_per_level)) - 1);
k_ |= (u64(start_idx) << (level * bits_per_level));
return find_first_leaf(level);
} else {
return false;
}
}
bool
radix_iterator2::find_first_leaf(u32 level)
{
// Find the first non-empty node after k_ on this level.
for (u32 idx = index(k_, level); idx < (1<<bits_per_level); idx++) {
void *next = node(level+1)->ptr[idx].ptr().load();
if (next != nullptr) {
if (index(k_, level) != idx) {
// We had to advance; clear everything this level and under
// and set this one.
k_ &= ~((1ULL<<((level+1) * bits_per_level)) - 1);
k_ |= (u64(idx) << (level * bits_per_level));
}
path_[level] = next;
if (level == 0 || find_first_leaf(level-1))
return true;
}
}
// Failed to find a leaf. Abort.
return false;
}
......@@ -26,7 +26,6 @@ struct pmu pmu;
struct pmulog {
u64 count;
u64 capacity;
u8 idle:1; // Currently idle?
struct pmuevent *event;
__padout__;
} __mpalign__;
......@@ -72,12 +71,6 @@ sampdump(void)
}
void
sampidle(bool b)
{
pmulog[myid()].idle = b;
}
void
sampconf(void)
{
pushcli();
......@@ -112,7 +105,7 @@ samplog(struct trapframe *tf)
e = &l->event[l->count];
e->idle = l->idle;
e->idle = (myproc() == idleproc());
e->rip = tf->rip;
getcallerpcs((void*)tf->rbp, e->trace, NELEM(e->trace));
l->count++;
......
......@@ -74,8 +74,6 @@ sched(void)
release(&myproc()->lock);
return;
}
} else {
sampidle(false);
}
if (next->get_state() != RUNNABLE)
......
......@@ -123,7 +123,6 @@ uwq::alloc(vmap* vmap, filetable *ftable)
}
if (mapkva(vmap->pml4, (char*)ipc, USERWQ, USERWQSIZE)) {
ksfree(slab_userwq, ipc);
u->dec();
return nullptr;
}
......
......@@ -685,12 +685,12 @@ vmap::sbrk(ssize_t n, uptr *addr)
auto curbrk = brk_;
*addr = curbrk;
if(n < 0 && 0 - n <= curbrk){
if(n <= 0 && 0 - n <= curbrk){
brk_ += n;
return 0;
}
if(n < 0 || n > USERTOP || curbrk + n > USERTOP)
if(n <= 0 || n > USERTOP || curbrk + n > USERTOP)
return -1;
// look one page ahead, to check if the newly allocated region would
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论