Commit ad3f704e authored by winckel's avatar winckel

Added item alloc and free functions.

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4745 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent fcde22a2
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
*******************************************************************************/ *******************************************************************************/
#include <stdint.h>
#include "assertions.h" #include "assertions.h"
#include "memory_pools.h" #include "memory_pools.h"
...@@ -49,9 +47,8 @@ typedef uint8_t pool_id_t; ...@@ -49,9 +47,8 @@ typedef uint8_t pool_id_t;
typedef struct memory_pool_item_start_s { typedef struct memory_pool_item_start_s {
pool_item_start_mark_t start_mark; pool_item_start_mark_t start_mark;
uint32_t info;
pool_id_t pool_id; pool_id_t pool_id;
uint32_t info;
} memory_pool_item_start_t; } memory_pool_item_start_t;
typedef struct memory_pool_item_end_s { typedef struct memory_pool_item_end_s {
...@@ -64,14 +61,19 @@ typedef struct memory_pool_item_s { ...@@ -64,14 +61,19 @@ typedef struct memory_pool_item_s {
memory_pool_item_end_t end; memory_pool_item_end_t end;
} memory_pool_item_t; } memory_pool_item_t;
typedef struct items_group_s {
volatile int32_t current;
volatile int32_t minimum;
int32_t *indexes;
} items_group_t;
typedef struct memory_pool_s { typedef struct memory_pool_s {
pool_start_mark_t start_mark; pool_start_mark_t start_mark;
pool_id_t pool_id; pool_id_t pool_id;
uint32_t items_number; uint32_t items_number;
uint32_t item_size; uint32_t item_size;
uint32_t items_free; items_group_t items_group_free;
uint32_t items_free_min;
memory_pool_item_t *items; memory_pool_item_t *items;
} memory_pool_t; } memory_pool_t;
...@@ -98,13 +100,69 @@ static const pools_start_mark_t POOLS_START_MARK = CHARS_TO_UINT32 ('P' ...@@ -98,13 +100,69 @@ static const pools_start_mark_t POOLS_START_MARK = CHARS_TO_UINT32 ('P'
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
static inline memory_pools_t *memory_pools_from_handler(memory_pools_handle_t *memory_pools_handle)
{
memory_pools_t *memory_pools;
/* Recover memory_pools */
memory_pools = (memory_pools_t *) memory_pools_handle;
/* Sanity check on passed handle */
DevAssert (memory_pools->start_mark == POOLS_START_MARK);
return (memory_pools);
}
static inline memory_pool_item_t *memory_pool_item_from_handler(memory_pool_item_handle_t *memory_pool_item_handle)
{
void *address;
memory_pool_item_t *memory_pool_item;
/* Recover memory_pools */
address = ((void *) memory_pool_item_handle) - sizeof (memory_pool_item_start_t);
memory_pool_item = (memory_pool_item_t *) address;
/* Sanity check on passed handle */
DevAssert (memory_pool_item->start.start_mark == POOL_ITEM_START_MARK);
return (memory_pool_item);
}
static inline int32_t items_group_get_free_item(items_group_t *items_group)
{
int32_t current;
int32_t index = -1;
/* Get current position and decrease it */
current = __sync_fetch_and_add (&items_group->current, -1);
if (current < 0)
{
/* Current index is not valid, restore previous value */
__sync_fetch_and_add (&items_group->current, 1);
}
else
{
/* Updates minimum position if needed */
while (items_group->minimum > current)
{
items_group->minimum = current;
}
/* Get index at current position */
index = items_group->indexes[current];
DevCheck (index >= 0, current, index, 0);
/* Clear index at current position */
items_group->indexes[current] = -1;
}
return (index);
}
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
memory_pools_handle_t *memory_pools_create (uint32_t pools_number) memory_pools_handle_t *memory_pools_create (uint32_t pools_number)
{ {
memory_pools_t *memory_pools; memory_pools_t *memory_pools;
uint32_t pool; pool_id_t pool;
DevCheck (pools_number < MAX_POOLS_NUMBER, pools_number, MAX_POOLS_NUMBER, 0); /* Limit to a reasonable number of pools */ DevCheck (pools_number < MAX_POOLS_NUMBER, pools_number, MAX_POOLS_NUMBER, 0); /* Limit to a reasonable number of pools */
...@@ -136,16 +194,17 @@ int memory_pools_add_pool (memory_pools_handle_t *memory_pools_handle, uint32_t ...@@ -136,16 +194,17 @@ int memory_pools_add_pool (memory_pools_handle_t *memory_pools_handle, uint32_t
{ {
memory_pools_t *memory_pools; memory_pools_t *memory_pools;
memory_pool_t *memory_pool; memory_pool_t *memory_pool;
uint32_t pool; pool_id_t pool;
uint32_t item; uint32_t item;
DevCheck (pool_items_number < MAX_POOL_ITEMS_NUMBER, pool_items_number, MAX_POOL_ITEMS_NUMBER, 0); /* Limit to a reasonable number of items */ DevCheck (pool_items_number < MAX_POOL_ITEMS_NUMBER, pool_items_number, MAX_POOL_ITEMS_NUMBER, 0); /* Limit to a reasonable number of items */
DevCheck (pool_item_size < MAX_POOL_ITEM_SIZE, pool_item_size, MAX_POOL_ITEM_SIZE, 0); /* Limit to a reasonable item size */ DevCheck (pool_item_size < MAX_POOL_ITEM_SIZE, pool_item_size, MAX_POOL_ITEM_SIZE, 0); /* Limit to a reasonable item size */
/* Recover memory_pools */ /* Recover memory_pools */
memory_pools = (memory_pools_t *) memory_pools_handle; memory_pools = memory_pools_from_handler (memory_pools_handle);
DevAssert (memory_pools->start_mark == POOLS_START_MARK); /* Sanity check on passed handle */
DevAssert (memory_pools->pools_defined < memory_pools->pools_number); /* Check number of already created pools */ /* Check number of already created pools */
DevAssert (memory_pools->pools_defined < memory_pools->pools_number);
/* Select pool */ /* Select pool */
pool = memory_pools->pools_defined; pool = memory_pools->pools_defined;
...@@ -153,21 +212,31 @@ int memory_pools_add_pool (memory_pools_handle_t *memory_pools_handle, uint32_t ...@@ -153,21 +212,31 @@ int memory_pools_add_pool (memory_pools_handle_t *memory_pools_handle, uint32_t
/* Initialize pool */ /* Initialize pool */
{ {
memory_pool->pool_id = pool + 1; memory_pool->pool_id = pool;
memory_pool->items_number = pool_items_number; memory_pool->items_number = pool_items_number;
memory_pool->item_size = pool_item_size; memory_pool->item_size = pool_item_size;
memory_pool->items_free = pool_items_number; memory_pool->items_group_free.current = pool_items_number - 1;
memory_pool->items_free_min = pool_items_number; memory_pool->items_group_free.minimum = pool_items_number - 1;
/* Allocate free indexes */
memory_pool->items_group_free.indexes = malloc(pool_items_number * sizeof(uint32_t));
DevAssert (memory_pool->items_group_free.indexes != NULL);
/* Initialize free indexes */
for (item = 0; item < pool_items_number; item++)
{
memory_pool->items_group_free.indexes[item] = item;
}
/* Allocate items */ /* Allocate items */
memory_pool->items = calloc (pool_items_number, (sizeof(memory_pool_item_t) + pool_item_size)); memory_pool->items = calloc (pool_items_number, (sizeof(memory_pool_item_t) + pool_item_size));
DevAssert (memory_pool->items != NULL); DevAssert (memory_pool->items != NULL);
/* Initialize items */ /* Initialize items */
for (item = 0; pool < pool_items_number; item++) for (item = 0; item < pool_items_number; item++)
{ {
memory_pool->items[item].start.start_mark = POOL_ITEM_START_MARK; memory_pool->items[item].start.start_mark = POOL_ITEM_START_MARK;
memory_pool->items[item].start.pool_id = memory_pool->pool_id; memory_pool->items[item].start.pool_id = pool;
memory_pool->items[item].data[pool_item_size / sizeof(uint32_t)] = POOL_ITEM_END_MARK; memory_pool->items[item].data[pool_item_size / sizeof(uint32_t)] = POOL_ITEM_END_MARK;
} }
} }
...@@ -177,3 +246,68 @@ int memory_pools_add_pool (memory_pools_handle_t *memory_pools_handle, uint32_t ...@@ -177,3 +246,68 @@ int memory_pools_add_pool (memory_pools_handle_t *memory_pools_handle, uint32_t
return (0); return (0);
} }
memory_pool_item_handle_t *memory_pools_allocate (memory_pools_handle_t *memory_pools_handle, uint32_t item_size)
{
memory_pools_t *memory_pools;
memory_pool_item_t *memory_pool_item = NULL;
pool_id_t pool;
int32_t item;
/* Recover memory_pools */
memory_pools = memory_pools_from_handler (memory_pools_handle);
for (pool = 0; pool <= memory_pools->pools_defined; pool++)
{
if (memory_pools->pools[pool].item_size < item_size)
{
/* This memory pool has too small items, skip it */
continue;
}
item = items_group_get_free_item(&memory_pools->pools[pool].items_group_free);
if (item < 0)
{
/* Allocation failed, skip this pool */
continue;
}
else
{
/* Allocation succeed, exit searching loop */
break;
}
}
if (item >= 0)
{
/* Convert item index into memory_pool_item address */
memory_pool_item = &memory_pools->pools[pool].items[item];
}
return (memory_pool_item_handle_t *) memory_pool_item->data;
}
void memory_pools_free (memory_pools_handle_t *memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle)
{
memory_pools_t *memory_pools;
memory_pool_item_t *memory_pool_item = NULL;
pool_id_t pool;
int32_t item;
uint32_t item_size;
/* Recover memory_pools */
memory_pools = memory_pools_from_handler (memory_pools_handle);
/* Recover memory pool item */
memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle);
/* Recover pool index */
pool = memory_pool_item->start.pool_id;
DevCheck (pool < memory_pools->pools_defined, pool, memory_pools->pools_defined, 0);
item_size = memory_pools->pools[pool].item_size;
item = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / (sizeof(memory_pool_item_t) + item_size);
/* Sanity check on calculated item index */
DevCheck (memory_pool_item == &memory_pools->pools[pool].items[item], memory_pool_item, &memory_pools->pools[pool].items[item], pool);
/* Check if end marker is still present (no write overflow) */
DevCheck (memory_pool_item->data[item_size / sizeof(uint32_t)] == POOL_ITEM_END_MARK, pool, 0, 0);
}
...@@ -31,6 +31,17 @@ ...@@ -31,6 +31,17 @@
#ifndef MEMORY_POOLS_H_ #ifndef MEMORY_POOLS_H_
#define MEMORY_POOLS_H_ #define MEMORY_POOLS_H_
#include <stdint.h>
typedef void * memory_pools_handle_t; typedef void * memory_pools_handle_t;
typedef void * memory_pool_item_handle_t;
memory_pools_handle_t *memory_pools_create (uint32_t pools_number);
int memory_pools_add_pool (memory_pools_handle_t *memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size);
memory_pool_item_handle_t *memory_pools_allocate (memory_pools_handle_t *memory_pools_handle, uint32_t item_size);
void memory_pools_free (memory_pools_handle_t *memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle);
#endif /* MEMORY_POOLS_H_ */ #endif /* MEMORY_POOLS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment