79 lines
2.2 KiB
C
79 lines
2.2 KiB
C
/**
|
|
* Replaceable memory allocator.
|
|
*/
|
|
#ifndef INCLUDED_REFCOUNT_ALLOCATOR_H
|
|
#define INCLUDED_REFCOUNT_ALLOCATOR_H
|
|
|
|
#include <ht.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* A set of the three main C standard allocators. Each member function should
|
|
* behave the same as its standard library counterpart. That is, for example,
|
|
* free should allow NULL as an input.
|
|
*
|
|
* To allow e.g. keeping track of allocations in different contexts, each
|
|
* function also takes a second user_data pointer argument.
|
|
*/
|
|
typedef struct RefcountAllocator {
|
|
union {
|
|
void *(*malloc)(size_t size); //!< malloc implementation which takes no
|
|
//!< data.
|
|
void *(*malloc_with_data)(
|
|
size_t size,
|
|
void *user_data); //!< malloc implementation that takes a data
|
|
//!< argument.
|
|
};
|
|
union {
|
|
void (*free)(void *ptr); //!< free implementation which takes no data.
|
|
void (*free_with_data)(void *ptr,
|
|
void *user_data); //!< free implementation that
|
|
//!< takes a data argument.
|
|
};
|
|
bool pass_data;
|
|
void *user_data;
|
|
} RefcountAllocator;
|
|
|
|
extern const RefcountAllocator *refcount_global_allocator;
|
|
|
|
/**
|
|
* Allocate memory using a #RefcountAllocator.
|
|
* @param alloc The allocator to use
|
|
* @param size The number of bytes to allocate
|
|
* @return The newly allocate pointer, or NULL if allocation failed
|
|
*/
|
|
static inline void *refcount_malloc(const RefcountAllocator *alloc,
|
|
size_t size) {
|
|
if (alloc->pass_data) {
|
|
return alloc->malloc_with_data(size, alloc->user_data);
|
|
}
|
|
return alloc->malloc(size);
|
|
}
|
|
|
|
/**
|
|
* Free memory using a #RefcountAllocator.
|
|
* @param alloc The allocator to use
|
|
* @param ptr The pointer to free
|
|
*/
|
|
static inline void refcount_free(const RefcountAllocator *alloc, void *ptr) {
|
|
if (alloc->pass_data) {
|
|
alloc->free_with_data(ptr, alloc->user_data);
|
|
} else {
|
|
alloc->free(ptr);
|
|
}
|
|
}
|
|
|
|
void refcount_allocator_to_ht_allocator(const RefcountAllocator *src,
|
|
HTAllocator *dest);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|