tuned granularity - amd64 only (for now) - VIRT 114 / RES 95

git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4300 77e5149b-7576-45b1-b177-96237e5ba77b
0.95
aCaB 17 years ago
parent e21657dfc9
commit 948644e619
  1. 63
      libclamav/mpool.c
  2. 90
      libclamav/mpool.h

@ -39,7 +39,7 @@
#include <stddef.h>
/* #define DEBUGMPOOL */
#define DEBUGMPOOL
#ifdef DEBUGMPOOL
#include <stdio.h>
FILE *lfd = NULL;
@ -50,16 +50,16 @@ FILE *lfd = NULL;
#include "mpool.h"
//#define MIN_FRAGSIZE 4096 /* 1m2.282s */
//#define MIN_FRAGSIZE 8192 /* 0m46.652s */
//#define MIN_FRAGSIZE 16384 /* 0m8.365s */
//#define MIN_FRAGSIZE 32768 /* 0m3.788s */
//#define MIN_FRAGSIZE 65536 /* 0m2.759s */
//#define MIN_FRAGSIZE 131072 /* 0m2.445s */
/* #define MIN_FRAGSIZE 4096 /\* 1m2.282s *\/ */
/* #define MIN_FRAGSIZE 8192 /\* 0m46.652s *\/ */
/* #define MIN_FRAGSIZE 16384 /\* 0m8.365s *\/ */
/* #define MIN_FRAGSIZE 32768 /\* 0m3.788s *\/ */
/* #define MIN_FRAGSIZE 65536 /\* 0m2.759s *\/ */
/* #define MIN_FRAGSIZE 131072 /\* 0m2.445s *\/ */
#define MIN_FRAGSIZE 262144 /* 0m2.343s */
//#define MIN_FRAGSIZE 524288 /* 0m2.387s */
//#define MIN_FRAGSIZE 1048576 /* 0m2.392s */
//#define MIN_FRAGSIZE 2097152 /* 0m2.402s */
/* #define MIN_FRAGSIZE 524288 /\* 0m2.387s *\/ */
/* #define MIN_FRAGSIZE 1048576 /\* 0m2.392s *\/ */
/* #define MIN_FRAGSIZE 2097152 /\* 0m2.402s *\/ */
struct FRAG {
@ -69,37 +69,44 @@ struct FRAG {
};
#define FRAG_OVERHEAD (offsetof(struct FRAG, fake))
#define align_to_voidptr(size) (((size) / sizeof(void *) + ((size) % sizeof(void *) != 0)) * sizeof(void *))
#define roundup(size) (FRAG_OVERHEAD + align_to_voidptr(size))
static unsigned int align_to_pagesize(struct MP *mp, unsigned int size) {
return (size / mp->psize + (size % mp->psize != 0)) * mp->psize;
}
static unsigned int align_to_voidptr(unsigned int size) {
return (size / sizeof(void *) + (size % sizeof(void *) != 0)) * sizeof(void *);
}
/* FIXME: use instead a bit2size table so we can spare bits and offer a better granularity */
static unsigned int to_bits(unsigned int size) {
unsigned int i;
for(i=0; i<32; i++)
if((unsigned int)1<<i >= size) return i;
for(i=0; i<FRAGSBITS; i++)
if(fragsz[i] >= size) return i;
return i; /* NOTREACHED */
}
static unsigned int from_bits(unsigned int bits) {
return 1<<bits;
return fragsz[bits];
}
/* static unsigned int to_bits(unsigned int size) { */
/* unsigned int i; */
/* for(i=0; i<32; i++) */
/* if((unsigned int)1<<i >= size) return i; */
/* return i; /\* NOTREACHED *\/ */
/* } */
/* static unsigned int from_bits(unsigned int bits) { */
/* return 1<<bits; */
/* } */
struct MP *mp_create() {
struct MP mp, *mp_p;
unsigned int sz;
memset(&mp, 0, sizeof(mp));
mp.psize = getpagesize();
#ifdef DEBUGMPOOL
lfd = fopen("mmpool_log", "w");
#endif
mp.fd = open("/dev/zero", O_RDWR, 0);
mp.top = align_to_pagesize(&mp, MIN_FRAGSIZE + 0*sizeof(mp));
sz = align_to_pagesize(&mp, MIN_FRAGSIZE);
mp.mpm.usize = align_to_voidptr(sizeof(struct MPMAP));
mp.mpm.size = mp.top - align_to_voidptr(sizeof(mp));
if ((mp_p = (struct MP *)mmap(NULL, mp.top, PROT_READ | PROT_WRITE, MAP_PRIVATE, mp.fd, 0)) == MAP_FAILED)
mp.mpm.size = sz - align_to_voidptr(sizeof(mp));
if ((mp_p = (struct MP *)mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)) == MAP_FAILED)
return NULL;
memcpy(mp_p, &mp, sizeof(mp));
spam("Map created @ %p->%p - size %u out of %u\n", mp_p, (void*)mp_p + mp.mpm.size, mp.mpm.usize, mp.mpm.size);
@ -108,7 +115,6 @@ struct MP *mp_create() {
void mp_destroy(struct MP *mp) {
struct MPMAP *mpm_next = mp->mpm.next, *mpm;
close(mp->fd);
while((mpm = mpm_next)) {
mpm_next = mpm->next;
munmap((void *)mpm, mpm->size);
@ -148,19 +154,21 @@ void *mp_malloc(struct MP *mp, size_t size) {
struct FRAG *f = NULL;
struct MPMAP *mpm = &mp->mpm;
// check_all(mp);
/* check_all(mp); */
if (!size) return NULL;
j = sbits+2;
if (j<7) j = 7;
if (j > 32) j = 32;
j=sbits;
for (i=sbits; i<j; i++)
if((f = mp->avail[i])) break;
/* Case 1: We have a free'd frag */
if(f) {
spam("malloc %p size %u (freed)\n"), f, size;
spam("malloc %p size %u (freed)\n", f, roundup(size));
mp->avail[i] = f->next;
return &f->fake;
}
@ -171,7 +179,7 @@ void *mp_malloc(struct MP *mp, size_t size) {
while(mpm) {
if(mpm->size - mpm->usize >= needed) {
f = (struct FRAG *)((void *)mpm + mpm->usize);
spam("malloc %p size %u (hole)\n", f, size);
spam("malloc %p size %u (hole)\n", f, roundup(size));
mpm->usize += needed;
f->sbits = sbits;
return &f->fake;
@ -185,17 +193,16 @@ void *mp_malloc(struct MP *mp, size_t size) {
else
i = align_to_pagesize(mp, MIN_FRAGSIZE);
if ((mpm = (struct MPMAP *)mmap(NULL, i, PROT_READ | PROT_WRITE, MAP_PRIVATE, mp->fd, mp->top)) == MAP_FAILED) {
if ((mpm = (struct MPMAP *)mmap(NULL, i, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) {
spam("failed to alloc %u bytes (%u requested)\n", i, size);
return NULL;
}
mp->top += i;
mpm->size = i;
mpm->usize = needed + align_to_voidptr(sizeof(*mpm));
mpm->next = mp->mpm.next;
mp->mpm.next = mpm;
f = (struct FRAG *)((void *)mpm + align_to_voidptr(sizeof(*mpm)));
spam("malloc %p size %u (new map)\n", f, size);
spam("malloc %p size %u (new map)\n", f, roundup(size));
f->sbits = sbits;
return &f->fake;
}

@ -22,6 +22,92 @@
#define MPOOL_H
#ifdef USE_MPOOL
static const unsigned int fragsz[] = {
24, /* (33067) */
32, /* (93876) */
40, /* (731459) */
48, /* (35286) */
56, /* (6930) */
64, /* (442013) */
72, /* (2706) */
80, /* (2252) */
88, /* (3631) */
96, /* (2594) */
104, /* (3679) */
112, /* (3697) */
120, /* (3991) */
128, /* (5141) */
136, /* (22458) */
144, /* (4320) */
152, /* (4296) */
160, /* (12177) */
168, /* (18024) */
/* 176, /\* (323) *\/ */
/* 184, /\* (329) *\/ */
/* 192, /\* (202) *\/ */
/* 200, /\* (221) *\/ */
/* 208, /\* (166) *\/ */
/* 216, /\* (179) *\/ */
/* 224, /\* (216) *\/ */
/* 232, /\* (172) *\/ */
/* 240, /\* (157) *\/ */
/* 248, /\* (178) *\/ */
256, /* (133) */
/* 264, /\* (157) *\/ */
/* 272, /\* (140) *\/ */
/* 280, /\* (161) *\/ */
/* 288, /\* (125) *\/ */
/* 296, /\* (141) *\/ */
/* 304, /\* (100) *\/ */
/* 312, /\* (97) *\/ */
/* 320, /\* (70) *\/ */
/* 328, /\* (13) *\/ */
/* 336, /\* (21) *\/ */
/* 344, /\* (21) *\/ */
/* 352, /\* (13) *\/ */
/* 360, /\* (9) *\/ */
/* 368, /\* (8) *\/ */
/* 376, /\* (14) *\/ */
/* 384, /\* (5) *\/ */
/* 392, /\* (6) *\/ */
/* 400, /\* (4) *\/ */
/* 408, /\* (2) *\/ */
/* 416, /\* (6) *\/ */
/* 424, /\* (5) *\/ */
/* 432, /\* (4) *\/ */
/* 440, /\* (4) *\/ */
/* 448, /\* (4) *\/ */
/* 464, /\* (2) *\/ */
/* 472, /\* (2) *\/ */
/* 480, /\* (1) *\/ */
/* 496, /\* (1) *\/ */
/* 512, /\* (2) *\/ */
520, /* (11) */
/* 536, /\* (1) *\/ */
/* 544, /\* (2) *\/ */
/* 552, /\* (1) *\/ */
/* 584, /\* (3) *\/ */
/* 600, /\* (1) *\/ */
/* 624, /\* (1) *\/ */
/* 656, /\* (1) *\/ */
/* 784, /\* (2) *\/ */
1032, /* (11) */
/* 2056, /\* (14) *\/ */
2064, /* (7456) */
4104, /* (14) */
8200, /* (9) */
16392, /* (6) */
32776, /* (4) */
63512, /* (7) */
134408, /* (1) */
507984, /* (7) */
1051040, /* (1) */
2097152
};
#define FRAGSBITS (sizeof(fragsz)/sizeof(fragsz[0]))
struct MPMAP {
struct MPMAP *next;
unsigned int size;
@ -29,10 +115,8 @@ struct MPMAP {
};
struct MP {
int fd;
unsigned int psize;
unsigned int top;
struct FRAG *avail[32];
struct FRAG *avail[FRAGSBITS];
struct MPMAP mpm;
};

Loading…
Cancel
Save