Skip to content

Commit

Permalink
Add allocator context to matras
Browse files Browse the repository at this point in the history
So that the user wouldn't be bound to use the global allocator, but
could specify per environment one. We need this for:

  tarantool/tarantool#1767
  • Loading branch information
locker committed Oct 19, 2016
1 parent 259e3ce commit afbfa57
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 20 deletions.
8 changes: 5 additions & 3 deletions small/matras.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ matras_log2(matras_id_t val)
*/
void
matras_create(struct matras *m, matras_id_t extent_size, matras_id_t block_size,
matras_alloc_func alloc_func, matras_free_func free_func)
matras_alloc_func alloc_func, matras_free_func free_func,
void *alloc_ctx)
{
/*extent_size must be power of 2 */
assert((extent_size & (extent_size - 1)) == 0);
Expand All @@ -56,6 +57,7 @@ matras_create(struct matras *m, matras_id_t extent_size, matras_id_t block_size,
m->extent_count = 0;
m->alloc_func = alloc_func;
m->free_func = free_func;
m->alloc_ctx = alloc_ctx;

matras_id_t log1 = matras_log2(extent_size);
matras_id_t log2 = matras_log2(block_size);
Expand Down Expand Up @@ -86,7 +88,7 @@ matras_reset(struct matras *m)
static inline void *
matras_alloc_extent(struct matras *m)
{
void *ext = m->alloc_func();
void *ext = m->alloc_func(m->alloc_ctx);
if (ext)
m->extent_count++;
return ext;
Expand All @@ -98,7 +100,7 @@ matras_alloc_extent(struct matras *m)
static inline void
matras_free_extent(struct matras *m, void *ext)
{
m->free_func(ext);
m->free_func(m->alloc_ctx, ext);
m->extent_count--;
}

Expand Down
9 changes: 6 additions & 3 deletions small/matras.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ typedef uint32_t matras_id_t;
* of size M). Is allowed to return NULL, but is not allowed
* to throw an exception
*/
typedef void *(*matras_alloc_func)();
typedef void (*matras_free_func)(void *);
typedef void *(*matras_alloc_func)(void *ctx);
typedef void (*matras_free_func)(void *ctx, void *ptr);

/**
* sruct matras_view represents appropriate mapping between
Expand Down Expand Up @@ -177,6 +177,8 @@ struct matras {
matras_alloc_func alloc_func;
/* External extent deallocator */
matras_free_func free_func;
/* Argument passed to extent allocator */
void *alloc_ctx;
};

/*
Expand Down Expand Up @@ -207,7 +209,8 @@ struct matras {
*/
void
matras_create(struct matras *m, matras_id_t extent_size, matras_id_t block_size,
matras_alloc_func alloc_func, matras_free_func free_func);
matras_alloc_func alloc_func, matras_free_func free_func,
void *alloc_ctx);

/**
* Free all memory used by an instance of matras and
Expand Down
33 changes: 19 additions & 14 deletions test/matras.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
#include <iostream>

static void *
pta_alloc();
pta_alloc(void *ctx);
static void
pta_free(void *p);
pta_free(void *ctx, void *p);

#define PROV_BLOCK_SIZE 16
#define PROV_EXTENT_SIZE 64
Expand Down Expand Up @@ -41,8 +41,9 @@ unsigned int alloc_err_inj_countdown = 0;
#define MATRAS_VERSION_COUNT 8

static void *
pta_alloc()
pta_alloc(void *ctx)
{
static_cast<void>(ctx);
if (alloc_err_inj_enabled) {
if (alloc_err_inj_countdown == 0)
return 0;
Expand All @@ -54,8 +55,9 @@ pta_alloc()
return p;
}
static void
pta_free(void *p)
pta_free(void *ctx, void *p)
{
static_cast<void>(ctx);
check(AllocatedBlocks.find(p) != AllocatedBlocks.end(), "Bad free");
AllocatedBlocks.erase(p);
delete [] static_cast<char *>(p);
Expand All @@ -73,7 +75,7 @@ void matras_alloc_test()

alloc_err_inj_enabled = false;
for (unsigned int i = 0; i <= maxCapacity; i++) {
matras_create(&mat, PROV_EXTENT_SIZE, PROV_BLOCK_SIZE, pta_alloc, pta_free);
matras_create(&mat, PROV_EXTENT_SIZE, PROV_BLOCK_SIZE, pta_alloc, pta_free, NULL);
check(1u << mat.log2_capacity == maxCapacity, "Wrong capacity!");
AllocatedItems.clear();
for (unsigned int j = 0; j < i; j++) {
Expand Down Expand Up @@ -116,7 +118,7 @@ void matras_alloc_test()
}

for (unsigned int i = 0; i <= maxCapacity; i++) {
matras_create(&mat, PROV_EXTENT_SIZE, PROV_BLOCK_SIZE, pta_alloc, pta_free);
matras_create(&mat, PROV_EXTENT_SIZE, PROV_BLOCK_SIZE, pta_alloc, pta_free, NULL);
for (unsigned int j = 0; j < i; j++) {
unsigned int res = 0;
(void) matras_alloc(&mat, &res);
Expand All @@ -132,7 +134,7 @@ void matras_alloc_test()

alloc_err_inj_enabled = true;
for (unsigned int i = 0; i <= maxCapacity; i++) {
matras_create(&mat, PROV_EXTENT_SIZE, PROV_BLOCK_SIZE, pta_alloc, pta_free);
matras_create(&mat, PROV_EXTENT_SIZE, PROV_BLOCK_SIZE, pta_alloc, pta_free, NULL);

alloc_err_inj_countdown = i;

Expand All @@ -154,17 +156,18 @@ void matras_alloc_test()

typedef uint64_t type_t;
const size_t VER_EXTENT_SIZE = 512;
int extents_in_use = 0;

void *all()
void *all(void *ctx)
{
extents_in_use++;
long *extents_in_use = static_cast<long *>(ctx);
++*extents_in_use;
return malloc(VER_EXTENT_SIZE);
}

void dea(void *p)
void dea(void *ctx, void *p)
{
extents_in_use--;
long *extents_in_use = static_cast<long *>(ctx);
--*extents_in_use;
free(p);
}

Expand Down Expand Up @@ -192,7 +195,8 @@ matras_vers_test()
int use_mask = 1;
int cur_num_or_ver = 1;
struct matras local;
matras_create(&local, VER_EXTENT_SIZE, sizeof(type_t), all, dea);
long extents_in_use = 0;
matras_create(&local, VER_EXTENT_SIZE, sizeof(type_t), all, dea, &extents_in_use);
type_t val = 0;
for (int s = 10; s < 8000; s = int(s * 1.5)) {
for (int k = 0; k < 800; k++) {
Expand Down Expand Up @@ -267,7 +271,8 @@ matras_gh_1145_test()
std::cout << "Testing matras gh-1145 test..." << std::endl;

struct matras local;
matras_create(&local, VER_EXTENT_SIZE, sizeof(type_t), all, dea);
long extents_in_use = 0;
matras_create(&local, VER_EXTENT_SIZE, sizeof(type_t), all, dea, &extents_in_use);
struct matras_view view;
matras_create_read_view(&local, &view);
matras_id_t id;
Expand Down

0 comments on commit afbfa57

Please sign in to comment.