Hash :
2bc8fa02
Author :
Date :
2012-04-17T10:14:24
Implement git_pool paged memory allocator This adds a `git_pool` object that can do simple paged memory allocation with free for the entire pool at once. Using this, you can replace many small allocations with large blocks that can then cheaply be doled out in small pieces. This is best used when you plan to free the small blocks all at once - for example, if they represent the parsed state from a file or data stream that are either all kept or all discarded. There are two real patterns of usage for `git_pools`: either for "string" allocation, where the item size is a single byte and you end up just packing the allocations in together, or for "fixed size" allocation where you are allocating a large object (e.g. a `git_oid`) and you generally just allocation single objects that can be tightly packed. Of course, you can use it for other things, but those two cases are the easiest.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
#include "clar_libgit2.h"
#include "pool.h"
#include "git2/oid.h"
void test_core_pool__0(void)
{
int i;
git_pool p;
void *ptr;
cl_git_pass(git_pool_init(&p, 1, 4000));
for (i = 1; i < 10000; i *= 2) {
ptr = git_pool_malloc(&p, i);
cl_assert(ptr != NULL);
cl_assert(git_pool__ptr_in_pool(&p, ptr));
cl_assert(!git_pool__ptr_in_pool(&p, &i));
}
/* 1+2+4+8+16+32+64+128+256+512+1024 -> original block */
/* 2048 -> 1 block */
/* 4096 -> 1 block */
/* 8192 -> 1 block */
cl_assert(git_pool__open_pages(&p) + git_pool__full_pages(&p) == 4);
git_pool_clear(&p);
}
void test_core_pool__1(void)
{
int i;
git_pool p;
cl_git_pass(git_pool_init(&p, 1, 4000));
for (i = 2010; i > 0; i--)
cl_assert(git_pool_malloc(&p, i) != NULL);
/* with fixed page size, allocation must end up with these values */
cl_assert(git_pool__open_pages(&p) == 1);
cl_assert(git_pool__full_pages(&p) == 505);
git_pool_clear(&p);
cl_git_pass(git_pool_init(&p, 1, 4100));
for (i = 2010; i > 0; i--)
cl_assert(git_pool_malloc(&p, i) != NULL);
/* with fixed page size, allocation must end up with these values */
cl_assert(git_pool__open_pages(&p) == 1);
cl_assert(git_pool__full_pages(&p) == 492);
git_pool_clear(&p);
}
static char to_hex[] = "0123456789abcdef";
void test_core_pool__2(void)
{
git_pool p;
char oid_hex[GIT_OID_HEXSZ];
git_oid *oid;
int i, j;
memset(oid_hex, '0', sizeof(oid_hex));
cl_git_pass(git_pool_init(&p, sizeof(git_oid), 100));
for (i = 1000; i < 10000; i++) {
oid = git_pool_malloc(&p, 1);
cl_assert(oid != NULL);
for (j = 0; j < 8; j++)
oid_hex[j] = to_hex[(i >> (4 * j)) & 0x0f];
cl_git_pass(git_oid_fromstr(oid, oid_hex));
}
/* with fixed page size, allocation must end up with these values */
cl_assert(git_pool__open_pages(&p) == 0);
cl_assert(git_pool__full_pages(&p) == 90);
git_pool_clear(&p);
}