eina: introduce an API for requesting memory near already allocated memory from an Eina_Mempool.

Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Differential Revision: https://phab.enlightenment.org/D10535
This commit is contained in:
Cedric BAIL 2019-10-25 08:01:35 -07:00
parent 1f445dd12d
commit fb5cf01977
6 changed files with 44 additions and 3 deletions

View File

@ -61,6 +61,11 @@ struct _Eina_Mempool_Backend
* @use eina_mempool_iterator_new
*/
Eina_Iterator *(*iterator)(void *data);
/** Function to allocate memory near already allocated memory.
* @since 1.24
* @use eina_mempool_malloc_near
*/
void *(*alloc_near)(void *data, void *after, void *before, unsigned int size);
};
struct _Eina_Mempool_Backend_ABI1
@ -80,6 +85,7 @@ struct _Eina_Mempool_Backend_ABI2
void (*repack)(void *data, Eina_Mempool_Repack_Cb cb, void *cb_data);
Eina_Bool (*from)(void *data, void *element);
Eina_Iterator *(*iterator)(void *data);
void *(*alloc_near)(void *data, void *after, void *before, unsigned int size);
};
struct _Eina_Mempool
@ -101,6 +107,14 @@ eina_mempool_malloc(Eina_Mempool *mp, unsigned int size)
return mp->backend.alloc(mp->backend_data, size);
}
static inline void *
eina_mempool_malloc_near(Eina_Mempool *mp, void *after, void *before, unsigned int size)
{
if (mp->backend2 && mp->backend2->alloc_near && (!(after == NULL && before == NULL)))
return mp->backend2->alloc_near(mp->backend_data, after, before, size);
return mp->backend.alloc(mp->backend_data, size);
}
static inline void *
eina_mempool_calloc(Eina_Mempool *mp, unsigned int size)
{

View File

@ -98,13 +98,14 @@ _new_va(const char *name,
SBP(shutdown);
#undef SBP
if (be->repack || be->from)
if (be->repack || be->from || be->iterator || be->alloc_near)
{
mp->backend2 = calloc(1, sizeof (Eina_Mempool_Backend_ABI2));
if (!mp->backend2) goto on_error;
mp->backend2->repack = be->repack;
mp->backend2->from = be->from;
mp->backend2->iterator = be->iterator;
mp->backend2->alloc_near = be->alloc_near;
}
mp->backend_data = mp->backend.init(context, options, args);

View File

@ -124,6 +124,29 @@ static inline void *eina_mempool_realloc(Eina_Mempool *mp, void *element, unsign
*/
static inline void *eina_mempool_malloc(Eina_Mempool *mp, unsigned int size) EINA_MALLOC EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
/**
* @brief Allocates memory in the given mempool using locality hint to improve future memory access use.
*
* @param[in] mp The mempool
* @param[in] after Hint to the nearest pointer after which to try find an empty spot.
* @param[in] before Hint to the nearest pointer before which to try find an empty spot.
* @param[in] size The size in bytes to allocate
* @return The newly allocated data that might be near @p after and @p before.
*
* This function is to be used to improve cache locality of structure that are likely to be used
* one after another. An example of this use would be Eina_List.
*
* @note This function allocates and returns @p size bytes using the mempool @p mp.
* If not used anymore, the data must be freed with eina_mempool_free().
* @note @p after and @p before must be either @c NULL or allocated by the same mempool
* @p mp. They are hint and if no space near them is found, memory will be allocated
* without locality improvement.
* @warning No checks are done for @p mp.
*
* @see eina_mempool_free()
*/
static inline void *eina_mempool_malloc_near(Eina_Mempool *mp, void *after, void *before, unsigned int size) EINA_WARN_UNUSED_RESULT;
/**
* @brief Allocates and zeros memory using the given mempool.
*

View File

@ -726,7 +726,8 @@ static Eina_Mempool_Backend _eina_chained_mp_backend = {
&eina_chained_mempool_shutdown,
&eina_chained_mempool_repack,
&eina_chained_mempool_from,
&eina_chained_mempool_iterator_new
&eina_chained_mempool_iterator_new,
NULL
};
Eina_Bool chained_init(void)

View File

@ -452,7 +452,8 @@ static Eina_Mempool_Backend _eina_one_big_mp_backend = {
&eina_one_big_shutdown,
NULL,
&eina_one_big_from,
&eina_one_big_iterator_new
&eina_one_big_iterator_new,
NULL
};
Eina_Bool one_big_init(void)

View File

@ -77,6 +77,7 @@ static Eina_Mempool_Backend _eina_pass_through_mp_backend = {
&eina_pass_through_shutdown,
NULL,
&eina_pass_through_from,
NULL,
NULL
};