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

explicit nbytes arg to kmfree

上级 731728ab
......@@ -17,6 +17,15 @@ struct buf : public rcu_freed {
buf() : rcu_freed("buf") {}
virtual void do_gc() { delete this; }
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(buf));
return kmalloc(sizeof(buf));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(buf));
}
};
#define B_BUSY 0x1 // buffer is locked by some process
#define B_VALID 0x2 // buffer has been read from disk
......
......@@ -104,11 +104,25 @@ struct range : public rcu_freed {
public:
range(crange *cr, u64 k, u64 sz, int nlevel = 0);
bool deleted() { return next[0].mark(); }
} __mpalign__;
struct range_head : public range {
range_head(crange *cr, u64 k, u64 sz, int nlevel)
: range(cr, k, sz, nlevel) {}
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(range_head));
return kmalloc(sizeof(range_head));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(range_head));
}
virtual void do_gc() {
delete this;
}
} __mpalign__;
};
class range_iterator {
private:
......@@ -128,7 +142,7 @@ class crange_locked;
struct crange {
private:
const int nlevel; // number of levels in the crange skip list
range *const crange_head; // a crange skip list starts with a sentinel range (key 0, sz 0)
range_head *const crange_head; // a crange skip list starts with a sentinel range (key 0, sz 0)
static void mark(range *f, range *s);
static int lock_range(u64 k, u64 sz, int l, range **er, range **pr, range **fr, range **lr, range **sr);
......@@ -151,6 +165,15 @@ struct crange {
range_iterator begin() const { return range_iterator(crange_head->next[0].ptr()); };
range_iterator end() const { return range_iterator(0); };
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(crange));
return kmalloc(sizeof(crange));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(crange));
}
};
static inline range_iterator
......
......@@ -42,6 +42,15 @@ struct inode : public rcu_freed {
inode();
~inode();
virtual void do_gc() { delete this; }
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(inode));
return kmalloc(sizeof(inode));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(inode));
}
};
#define I_BUSYR 0x1
......
......@@ -118,10 +118,10 @@ char* kalloc(void);
void kfree(void*);
void* ksalloc(int slabtype);
void ksfree(int slabtype, void*);
void* kmalloc(u64);
void kmfree(void*);
void* kmalloc(u64 nbytes);
void kmfree(void*, u64 nbytes);
int kmalign(void **p, int align, u64 size);
void kmalignfree(void *);
void kmalignfree(void *, int align, u64 size);
void verifyfree(char *ptr, u64 nbytes);
void kminit(void);
......
......@@ -20,7 +20,18 @@ class xelem : public rcu_freed {
K key;
xelem(const K &k, const V &v) : rcu_freed("xelem"), val(v), next_lock(0), next(0), key(k) {}
virtual void do_gc() { delete this; }
virtual void do_gc() {
delete this;
}
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(xelem));
return kmalloc(sizeof(xelem));
}
static void operator delete(void *p) {
kmfree(p, sizeof(xelem));
}
};
template<class K, class V>
......@@ -215,6 +226,15 @@ class xns : public rcu_freed {
iterator end() {
return iterator();
}
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(xns));
return kmalloc(sizeof(xns));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(xns));
}
};
template<class K, class V, u64 (*HF)(const K&)>
......
......@@ -26,6 +26,15 @@ struct vmnode {
vmnode* copy();
int demand_load();
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(vmnode));
return kmalloc(sizeof(vmnode));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(vmnode));
}
};
// A mapping of a chunk of an address space to
......@@ -42,6 +51,15 @@ struct vma : public range {
~vma();
virtual void do_gc() { delete this; }
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(vma));
return kmalloc(sizeof(vma));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(vma));
}
};
// An address space: a set of vmas plus h/w page table.
......@@ -66,6 +84,15 @@ struct vmap {
int pagefault(uptr va, u32 err);
int copyout(uptr va, void *p, u64 len);
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(vmap));
return kmalloc(sizeof(vmap));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(vmap));
}
private:
int pagefault_wcow(vma *m);
};
......@@ -3,33 +3,19 @@
#include "cpputil.hh"
void *
operator new(unsigned long nbytes)
{
return kmalloc(nbytes);
}
void *
operator new(unsigned long nbytes, void *buf)
{
return buf;
}
void *
operator new[](unsigned long nbytes)
{
return kmalloc(nbytes);
}
void
operator delete(void *p)
{
kmfree(p);
u64 *x = (u64*) kmalloc(nbytes + sizeof(u64));
*x = nbytes;
return x+1;
}
void
operator delete[](void *p)
{
kmfree(p);
u64 *x = (u64*) p;
x--;
kmfree(x, *x);
}
void
......
......@@ -91,7 +91,7 @@ range::~range()
for (int l = 0; l < nlevel; l++) {
next[l] = (struct range *) 0xDEADBEEF;
}
kmalignfree(lock);
kmalignfree(lock, CACHELINE, sizeof(struct spinlock));
delete[] next;
}
......@@ -176,7 +176,7 @@ crange::print(int full)
}
crange::crange(int nl)
: nlevel(nl), crange_head(new range(this, 0, 0, nlevel))
: nlevel(nl), crange_head(new range_head(this, 0, 0, nlevel))
{
assert(nl > 0);
dprintf("crange::crange return 0x%lx\n", (u64) this);
......
......@@ -42,7 +42,7 @@ fileclose(struct file *f)
netclose(f->socket);
else
panic("fileclose bad type");
kmfree(f);
kmfree(f, sizeof(struct file));
}
// Get metadata about file f.
......
......@@ -484,6 +484,15 @@ class diskblock : public rcu_freed {
bfree(_dev, _block);
delete this;
}
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(diskblock));
return kmalloc(sizeof(diskblock));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(diskblock));
}
};
static void
......
......@@ -162,12 +162,12 @@ kalloc_pool(struct kmem *km)
m = &km[cn];
r = m->freelist;
while (r && !cmpxch(&m->freelist, r, r->next))
while (r && !cmpxch_update(&m->freelist, &r, r->next))
; /* spin */
if (r) {
m->freelist = r->next;
m->nfree--;
break;
}
}
......
......@@ -43,23 +43,22 @@ morecore(int c, int b)
return -1;
int sz = 1 << b;
for(char *q = p;
q + sz + sizeof(struct header) <= p + PGSIZE;
q += sz + sizeof(struct header)){
for(char *q = p; q + sz <= p + PGSIZE; q += sz){
struct header *h = (struct header *) q;
h->next = freelists[c].buckets[b];
freelists[c].buckets[b] = h;
while (!cmpxch_update(&freelists[c].buckets[b], &h->next, h))
; /* spin */
}
return 0;
}
void *
kmalloc(u64 nbytes)
static int
bucket(u64 nbytes)
{
int nn = 1, b = 0;
u64 nn = 8, b = 3;
while(nn < nbytes && b <= KMMAX){
while(nn < nbytes) {
nn *= 2;
b++;
}
......@@ -68,6 +67,14 @@ kmalloc(u64 nbytes)
if(b > KMMAX)
panic("kmalloc too big");
return b;
}
void *
kmalloc(u64 nbytes)
{
int b = bucket(nbytes);
scoped_gc_epoch gc;
struct header *h;
int c = mycpu()->id;
......@@ -85,29 +92,23 @@ kmalloc(u64 nbytes)
}
}
void *r = h + 1;
h->next = (header*) (long) b;
mtlabel(mtrace_label_heap, r, nbytes, "kmalloc'ed", sizeof("kmalloc'ed"));
return r;
mtlabel(mtrace_label_heap, (void*) h, nbytes, "kmalloc'ed", sizeof("kmalloc'ed"));
return h;
}
void
kmfree(void *ap)
kmfree(void *ap, u64 nbytes)
{
int c = mycpu()->id;
struct header *h;
int b;
h = (struct header *) ((char *)ap - sizeof(struct header));
b = (long) h->next;
int b = bucket(nbytes);
if(b < 0 || b > KMMAX)
panic("kmfree bad bucket");
verifyfree((char*) ap, (1<<b) - sizeof(struct header));
struct header *h = (struct header *) ap;
verifyfree((char *) ap, (1<<b));
if (ALLOC_MEMSET)
memset(ap, 3, (1<<b) - sizeof(struct header));
memset(ap, 3, (1<<b));
int c = mycpu()->id;
h->next = freelists[c].buckets[b];
while (!cmpxch_update(&freelists[c].buckets[b], &h->next, h))
; /* spin */
......@@ -126,7 +127,8 @@ kmalign(void **p, int align, u64 size)
return 0;
}
void kmalignfree(void *mem)
void kmalignfree(void *mem, int align, u64 size)
{
kmfree(((void**)mem)[-1]);
u64 msz = size + (align-1) + sizeof(void*);
kmfree(((void**)mem)[-1], msz);
}
......@@ -288,7 +288,7 @@ netbind(int sock, void *xaddr, int xaddrlen)
lwip_core_lock();
r = lwip_bind(sock, (const sockaddr*) addr, xaddrlen);
lwip_core_unlock();
kmfree(addr);
kmfree(addr, xaddrlen);
return r;
}
......@@ -322,7 +322,7 @@ netaccept(int sock, void *xaddr, void *xaddrlen)
ss = lwip_accept(sock, (sockaddr*) addr, &len);
lwip_core_unlock();
if (ss < 0) {
kmfree(addr);
kmfree(addr, len);
return ss;
}
......@@ -330,7 +330,7 @@ netaccept(int sock, void *xaddr, void *xaddrlen)
lwip_core_lock();
lwip_close(ss);
lwip_core_unlock();
kmfree(addr);
kmfree(addr, len);
return -1;
}
......
......@@ -177,25 +177,32 @@ exit(void)
panic("zombie exit");
}
class delayedfree : public rcu_freed {
class delayed_proc_free : public rcu_freed {
private:
proc *_p;
public:
delayedfree(proc *p) : rcu_freed("delayed proc free"), _p(p) {}
delayed_proc_free(proc *p) : rcu_freed("delayed proc free"), _p(p) {}
virtual void do_gc() {
kmfree(_p);
kmfree(_p, sizeof(struct proc));
delete this;
}
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(delayed_proc_free));
return kmalloc(sizeof(delayed_proc_free));
}
static void operator delete(void *p) {
return kmfree(p, sizeof(delayed_proc_free));
}
};
static void
freeproc(struct proc *p)
{
destroylock(&p->lock);
delayedfree *df = new delayedfree(p);
gc_delayed(df);
gc_delayed(new delayed_proc_free(p));
}
// Look in the process table for an UNUSED proc.
......
......@@ -199,7 +199,7 @@ sampread(struct inode *ip, char *dst, u32 off, u32 n)
cc = MIN(LOGHEADER_SZ-off, n);
memmove(dst, (char*)hdr + off, cc);
kmfree(hdr);
kmfree(hdr, len);
n -= cc;
ret += cc;
......
......@@ -198,7 +198,7 @@ lwip_thread(void *x)
lwip_core_lock();
lt->thread(lt->arg);
lwip_core_unlock();
kmfree(lt);
kmfree(lt, sizeof(*lt));
}
sys_thread_t
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论