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

explicit nbytes arg to kmfree

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