61
/* #define MIN_FRAGSIZE 4096 /\* 1m2.282s *\/ */
62
/* #define MIN_FRAGSIZE 8192 /\* 0m46.652s *\/ */
63
/* #define MIN_FRAGSIZE 16384 /\* 0m8.365s *\/ */
64
/* #define MIN_FRAGSIZE 32768 /\* 0m3.788s *\/ */
65
/* #define MIN_FRAGSIZE 65536 /\* 0m2.759s *\/ */
66
/* #define MIN_FRAGSIZE 131072 /\* 0m2.445s *\/ */
67
#define MIN_FRAGSIZE 262144 /* 0m2.343s */
68
/* #define MIN_FRAGSIZE 524288 /\* 0m2.387s *\/ */
69
/* #define MIN_FRAGSIZE 1048576 /\* 0m2.392s *\/ */
70
/* #define MIN_FRAGSIZE 2097152 /\* 0m2.402s *\/ */
71
/* #define MIN_FRAGSIZE 99688128 */
62
#define MIN_FRAGSIZE 262144
73
64
#if SIZEOF_VOID_P==8
74
65
static const unsigned int fragsz[] = {
157
/* ^^ This shouldn't be reached but it's a good fall back
158
* MAX_ALLOCATION is 184549376 but that's really not need here */
66
/* SIZE PERM TEMP ACT! */
67
16, /* 7631 7189 USE/POW2 */
68
24, /* 81785 114 USE */
69
32, /* 1099428 78 USE/POW2 */
70
40, /* 22466 69 USE */
73
64, /* 2801 31 USE/POW2 */
74
72, /* 610137 29 USE */
78
104, /* 3669 24 USE */
79
112, /* 3897 23 USE */
80
120, /* 5105 22 USE */
81
128, /* 3097 22 USE/POW2 */
82
136, /* 3977 21 USE */
83
144, /* 32225 21 USE */
84
152, /* 12384 20 USE */
85
160, /* 17258 20 USE */
90
256, /* 516 19 USE/POW2 */
97
2056, /* 11408 16 USE */
101
10240, /* 1 11 USE */
102
16384, /* 0 8 POW2 */
108
65536, /* 0 3 POW2 */
110
102624, /* 1 1 USE */
111
131072, /* 0 1 POW2 */
112
147296, /* 1 1 USE */
113
262144, /* 0 1 POW2 */
114
369280, /* 1 0 USE */
115
507976, /* 9 0 USE */
116
525976, /* 1 0 USE */
117
1048576, /* 0 0 USE/POW2 */
121
/* MAX_ALLOCATION is 184549376 but that's really not need here */
163
126
static const unsigned int fragsz[] = {
127
/* SIZE PERM TEMP ACT! */
128
8, /* 1992 7188 USE/POW2 */
129
16, /* 49976 172 USE/POW2 */
130
24, /* 995096 121 USE */
131
32, /* 151077 68 USE/POW2 */
132
40, /* 15175 58 USE */
133
48, /* 7231 55 USE */
134
56, /* 613432 47 USE */
135
64, /* 1925 44 USE/POW2 */
136
72, /* 3192 42 USE */
137
80, /* 2782 40 USE */
138
88, /* 3524 40 USE */
139
96, /* 3395 40 USE */
140
104, /* 3593 40 USE */
141
112, /* 31850 40 USE */
142
120, /* 5260 38 USE */
143
128, /* 3231 38 USE/POW2 */
144
136, /* 4785 38 USE */
145
144, /* 3000 38 USE */
146
152, /* 13384 38 USE */
147
160, /* 14915 36 USE */
148
168, /* 485 36 USE */
149
176, /* 379 36 USE */
150
184, /* 322 36 USE */
151
192, /* 260 36 USE */
152
200, /* 410 36 USE */
153
208, /* 388 36 USE */
154
216, /* 262 36 USE */
155
224, /* 256 36 USE */
156
232, /* 475 36 USE */
157
248, /* 544 36 USE */
158
256, /* 206 36 POW2 */
159
264, /* 352 36 USE */
160
280, /* 258 36 USE */
161
296, /* 283 36 USE */
162
304, /* 308 36 USE */
163
312, /* 566 36 USE */
167
1032, /* 11408 32 USE */
168
2048, /* 0 32 POW2 */
169
4096, /* 0 28 POW2 */
171
8192, /* 0 16 POW2 */
172
10272, /* 1 14 USE */
173
18656, /* 1 11 USE */
175
32768, /* 0 6 POW2 */
178
65536, /* 0 2 POW2 */
179
131072, /* 0 2 POW2 */
180
147288, /* 1 2 USE */
181
184624, /* 1 0 USE */
182
253992, /* 9 0 USE */
183
262144, /* 0 0 POW2 */
184
525752, /* 1 0 USE */
185
1048576, /* 0 0 USE/POW2 */
304
191
#define FRAGSBITS (sizeof(fragsz)/sizeof(fragsz[0]))
328
215
#define FRAG_OVERHEAD (offsetof(struct FRAG, fake))
330
#define align_to_voidptr(size) (((size) / sizeof(void *) + ((size) % sizeof(void *) != 0)) * sizeof(void *))
217
#define align_to_voidptr(size) (((size) / MAX(sizeof(void *), 8) + ((size) % MAX(sizeof(void *), 8) != 0)) * MAX(sizeof(void *), 8))
331
218
#define mpool_roundup(size) (FRAG_OVERHEAD + align_to_voidptr(size))
333
220
static unsigned int align_to_pagesize(struct MP *mp, unsigned int size) {
349
236
struct MP mp, *mpool_p;
351
238
memset(&mp, 0, sizeof(mp));
352
mp.psize = getpagesize();
239
mp.psize = cli_getpagesize();
353
240
sz = align_to_pagesize(&mp, MIN_FRAGSIZE);
354
241
mp.mpm.usize = align_to_voidptr(sizeof(struct MPMAP));
355
242
mp.mpm.size = sz - align_to_voidptr(sizeof(mp));
359
246
memset(mpool_p, ALLOCPOISON, sz);
361
248
memcpy(mpool_p, &mp, sizeof(mp));
362
spam("Map created @ %p->%p - size %u out of %u\n", mpool_p, (char *)mpool_p + mp.mpm.size, mp.mpm.usize, mp.mpm.size);
249
spam("Map created @%p->%p - size %u out of %u - voidptr=%u\n", mpool_p, (char *)mpool_p + mp.mpm.size, mp.mpm.usize, mp.mpm.size, SIZEOF_VOID_P);
380
267
memset(mp, FREEPOISON, mpmsize + align_to_voidptr(sizeof(*mp)));
382
269
munmap((void *)mp, mpmsize + align_to_voidptr(sizeof(*mp)));
383
spam("Map destroyed @ %p\n", mp);
270
spam("Map destroyed @%p\n", mp);
386
273
void mpool_flush(struct MP *mp) {
387
size_t used = 0, mused;
388
struct MPMAP *mpm_next = mp->mpm.next, *mpm;
390
while((mpm = mpm_next)) {
391
mpm_next = mpm->next;
393
memset((char *)mpm + align_to_pagesize(mp, mpm->usize), FREEPOISON, mpm->size - align_to_pagesize(mp, mpm->usize));
395
munmap((char *)mpm + align_to_pagesize(mp, mpm->usize), mpm->size - align_to_pagesize(mp, mpm->usize));
396
mpm->size = align_to_pagesize(mp, mpm->usize);
399
mused = align_to_pagesize(mp, mp->mpm.usize + align_to_voidptr(sizeof(*mp)));
400
if (mused < mp->mpm.size) {
402
memset((char *)&mp->mpm + mused, FREEPOISON, mp->mpm.size - mused);
404
munmap((char *)&mp->mpm + mused, mp->mpm.size - mused);
405
mp->mpm.size = mused;
407
used += mp->mpm.size;
408
spam("Map flushed @ %p, in use: %lu\n", mp, used);
274
size_t used = 0, mused;
275
struct MPMAP *mpm_next = mp->mpm.next, *mpm;
281
while((mpm = mpm_next)) {
282
mpm_next = mpm->next;
283
mused = align_to_pagesize(mp, mpm->usize);
284
if(mused < mpm->size) {
286
memset((char *)mpm + mused, FREEPOISON, mpm->size - mused);
288
munmap((char *)mpm + mused, mpm->size - mused);
294
mused = align_to_pagesize(mp, mp->mpm.usize + align_to_voidptr(sizeof(*mp)));
295
if (mused < mp->mpm.size + align_to_voidptr(sizeof(*mp))) {
297
memset((char *)mp + mused, FREEPOISON, mp->mpm.size + align_to_voidptr(sizeof(*mp)) - mused);
299
munmap((char *)mp + mused, mp->mpm.size + align_to_voidptr(sizeof(*mp)) - mused);
300
mp->mpm.size = mused - align_to_voidptr(sizeof(*mp));
302
used += mp->mpm.size;
303
spam("Map flushed @%p, in use: %lu\n", mp, used);
411
306
int mpool_getstats(const struct cl_engine *eng, size_t *used, size_t *total)
444
339
/* Case 1: We have a free'd frag */
445
340
if((f = mp->avail[sbits])) {
446
spam("malloc %p size %u (freed)\n", f, mpool_roundup(size));
341
spam("malloc @%p size %u (freed)\n", f, align_to_voidptr(size + FRAG_OVERHEAD));
447
342
mp->avail[sbits] = f->u.next;
448
343
f->u.sbits = sbits;
463
358
if(mpm->size - mpm->usize >= needed) {
464
359
f = (struct FRAG *)((char *)mpm + mpm->usize);
465
spam("malloc %p size %u (hole)\n", f, mpool_roundup(size));
360
spam("malloc @%p size %u (hole)\n", f, align_to_voidptr(size + FRAG_OVERHEAD));
466
361
mpm->usize += needed;
467
362
f->u.sbits = sbits;
493
388
mpm->next = mp->mpm.next;
494
389
mp->mpm.next = mpm;
495
390
f = (struct FRAG *)((char *)mpm + align_to_voidptr(sizeof(*mpm)));
496
spam("malloc %p size %u (new map)\n", f, mpool_roundup(size));
391
spam("malloc @%p size %u (new map)\n", f, align_to_voidptr(size + FRAG_OVERHEAD));
497
392
f->u.sbits = sbits;
499
394
f->magic = MPOOLMAGIC;
534
429
if (!ptr) return mpool_malloc(mp, size);
536
spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->u.sbits), size);
537
431
if(!size || !(csize = from_bits(f->u.sbits))) {
538
432
cli_errmsg("mpool_realloc(): Attempt to allocate %lu bytes. Please report to http://bugs.clamav.net\n", (unsigned long int) size);
541
435
csize -= FRAG_OVERHEAD;
542
if (csize >= size && (!f->u.sbits || from_bits(f->u.sbits-1)-FRAG_OVERHEAD < size))
436
if (csize >= size && (!f->u.sbits || from_bits(f->u.sbits-1)-FRAG_OVERHEAD < size)) {
437
spam("free @%p\n", f);
438
spam("malloc @%p size %u (self)\n", f, align_to_voidptr(size + FRAG_OVERHEAD));
544
441
if (!(new_ptr = mpool_malloc(mp, size)))
546
443
memcpy(new_ptr, ptr, csize <= size ? csize : size);
551
448
void *mpool_realloc2(struct MP *mp, void *ptr, size_t size) {
552
struct FRAG *f = (struct FRAG *)((char *)ptr - FRAG_OVERHEAD);
556
if (!ptr) return mpool_malloc(mp, size);
558
spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->u.sbits), size);
559
if(!size || !(csize = from_bits(f->u.sbits))) {
560
cli_errmsg("mpool_realloc2(): Attempt to allocate %lu bytes. Please report to http://bugs.clamav.net\n", (unsigned long int) size);
449
void *new_ptr = mpool_realloc(mp, ptr, size);
561
452
mpool_free(mp, ptr);
564
csize -= FRAG_OVERHEAD;
565
if (csize >= size && (!f->u.sbits || from_bits(f->u.sbits-1)-FRAG_OVERHEAD < size))
567
if ((new_ptr = mpool_malloc(mp, size)))
568
memcpy(new_ptr, ptr, csize);
573
456
unsigned char *cli_mpool_hex2str(mpool_t *mp, const unsigned char *hex) {