Commit b6abfce9 authored by winckel's avatar winckel
Browse files

Updated destination task info in MP.

Modified MP item group handling to avoid delaying task when freeing items, ok for RTAI use.

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4774 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent fc8f8185
......@@ -391,6 +391,8 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
{
#if defined(OAI_EMU) || defined(RTAI)
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_ENQUEUE_MESSAGE, VCD_FUNCTION_IN);
memory_pools_set_info (itti_desc.memory_pools_handle, message, 1, destination_task_id);
#endif
if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED)
......
......@@ -61,15 +61,25 @@ uint64_t vcd_mp_free;
/*------------------------------------------------------------------------------*/
#define CHARS_TO_UINT32(c1, c2, c3, c4) (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4))
#define MEMORY_POOL_ITEM_INFO_NUMBER 2
/*------------------------------------------------------------------------------*/
typedef int32_t items_group_position_t;
typedef int32_t items_group_index_t;
typedef union items_group_positions_u {
uint64_t all;
struct {
items_group_position_t put;
items_group_position_t get;
} ind;
} items_group_positions_t;
typedef struct items_group_s {
items_group_position_t number;
volatile items_group_position_t current;
volatile items_group_position_t minimum;
volatile items_group_index_t *indexes;
items_group_position_t number_plus_one;
volatile uint32_t minimum;
volatile items_group_positions_t positions;
volatile items_group_index_t *indexes;
} items_group_t;
/*------------------------------------------------------------------------------*/
......@@ -94,7 +104,7 @@ typedef struct memory_pool_item_start_s {
pool_id_t pool_id;
item_status_t item_status;
uint16_t info[2];
uint16_t info[MEMORY_POOL_ITEM_INFO_NUMBER];
} memory_pool_item_start_t;
typedef struct memory_pool_item_end_s {
......@@ -142,32 +152,70 @@ static const pool_start_mark_t POOL_START_MARK = CHARS_TO_UINT32 ('P'
static const pools_start_mark_t POOLS_START_MARK = CHARS_TO_UINT32 ('P', 'S', 's', 't');
/*------------------------------------------------------------------------------*/
static inline items_group_index_t items_group_get_free_item (items_group_t *items_group)
static inline uint32_t items_group_number_items (items_group_t *items_group)
{
items_group_position_t current;
items_group_index_t index = -1;
return items_group->number_plus_one - 1;
}
static inline uint32_t items_group_free_items (items_group_t *items_group)
{
items_group_positions_t positions;
uint32_t free_items;
positions.all = items_group->positions.all;
/* Get current position and decrease it */
current = __sync_fetch_and_add (&items_group->current, -1);
if (current <= ITEMS_GROUP_POSITION_INVALID)
free_items = items_group->number_plus_one + positions.ind.put - positions.ind.get;
free_items %= items_group->number_plus_one;
return free_items;
}
static inline items_group_index_t items_group_get_free_item (items_group_t *items_group)
{
items_group_position_t get_raw;
items_group_position_t put;
items_group_position_t get;
items_group_position_t free_items;
items_group_index_t index = ITEMS_GROUP_INDEX_INVALID;
/* Get current put position */
put = items_group->positions.ind.put % items_group->number_plus_one;
/* Get current get position and increase it */
get_raw = __sync_fetch_and_add (&items_group->positions.ind.get, 1);
get = get_raw % items_group->number_plus_one;
if(put == get)
{
/* Current index is not valid, restore previous value */
__sync_fetch_and_add (&items_group->current, 1);
/* No more item free, restore previous position */
__sync_fetch_and_sub (&items_group->positions.ind.get, 1);
}
else
{
/* Updates minimum position if needed */
while (items_group->minimum > current)
/* Get index at current get position */
index = items_group->indexes[get];
if (index <= ITEMS_GROUP_INDEX_INVALID)
{
items_group->minimum = current;
/* Index has not yet been completely freed, restore previous get position */
__sync_fetch_and_sub (&items_group->positions.ind.get, 1);
}
else
{
if (get_raw == items_group->number_plus_one)
{
/* Wrap get position */
__sync_fetch_and_sub (&items_group->positions.ind.get, items_group->number_plus_one);
}
/* Get index at current position */
index = items_group->indexes[current];
AssertError (index > ITEMS_GROUP_INDEX_INVALID, "Index (%d) at current position (%d) is not valid!\n", current, index);
free_items = items_group_free_items(items_group);
/* Updates minimum free items if needed */
while (items_group->minimum > free_items)
{
items_group->minimum = free_items;
}
/* Clear index at current position */
items_group->indexes[current] = ITEMS_GROUP_INDEX_INVALID;
/* Clear index at current get position to indicate that item is free */
items_group->indexes[get] = ITEMS_GROUP_INDEX_INVALID;
}
}
return (index);
......@@ -175,65 +223,23 @@ static inline items_group_index_t items_group_get_free_item (items_group_t *item
static inline void items_group_put_free_item (items_group_t *items_group, items_group_index_t index)
{
items_group_position_t next;
items_group_position_t current = ITEMS_GROUP_POSITION_INVALID;
items_group_index_t index_to_add;
items_group_index_t index_previous;
items_group_position_t put_raw;
items_group_position_t put;
index_to_add = index - ITEMS_GROUP_INDEX_INVALID;
/* Get current put position and increase it */
put_raw = __sync_fetch_and_add (&items_group->positions.ind.put, 1);
put = put_raw % items_group->number_plus_one;
do
if (put_raw == items_group->number_plus_one)
{
/* Calculate next position */
next = items_group->current + 1;
/* Checks if next position is free */
if (items_group->indexes[next] != ITEMS_GROUP_INDEX_INVALID)
{
MP_DEBUG(" items_group_put_free_item (items_group->indexes[next] != ITEMS_GROUP_INDEX_INVALID) %d, %d\n", next, index);
}
else
{
/* Try to write index in next position */
index_previous = __sync_fetch_and_add (&items_group->indexes[next], index_to_add);
/* Checks if next position was still free */
if (index_previous != ITEMS_GROUP_INDEX_INVALID)
{
/* Next position was not free anymore, restore its value */
__sync_fetch_and_add (&items_group->indexes[next], -index_to_add);
current = ITEMS_GROUP_POSITION_INVALID;
/* Wrap position */
__sync_fetch_and_sub (&items_group->positions.ind.put, items_group->number_plus_one);
}
MP_DEBUG(" items_group_put_free_item (index_previous != ITEMS_GROUP_INDEX_INVALID) %d\n", index);
}
else
{
/* Checks if next position content is correctly set */
if (items_group->indexes[next] != index)
{
/* Next position content has been changed, restore its value */
__sync_fetch_and_add (&items_group->indexes[next], -index_to_add);
current = ITEMS_GROUP_POSITION_INVALID;
MP_DEBUG(" items_group_put_free_item (items_group->indexes[next] != index) %d\n", index);
}
else
{
/* Increase current position and get it */
current = __sync_add_and_fetch (&items_group->current, 1);
if (next != current)
{
/* Current position does not match calculated next position, restore previous values */
__sync_fetch_and_add (&items_group->current, -1);
__sync_fetch_and_add (&items_group->indexes[next], -index_to_add);
MP_DEBUG(" items_group_put_free_item (next != current) %d\n", index);
}
}
}
}
} while (next != current);
AssertFatal (items_group->indexes[put] <= ITEMS_GROUP_INDEX_INVALID, "Index at current put position (%d) is not marked as free (%d)\n", put, items_group->number_plus_one);
AssertFatal (current < items_group->number, "Current position (%d) is above maximum position (%d)\n", current, items_group->number);
/* Save freed item index at current put position */
items_group->indexes[put] = index;
}
/*------------------------------------------------------------------------------*/
......@@ -314,23 +320,28 @@ char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle)
int printed_chars;
uint32_t allocated_pool_memory;
uint32_t allocated_pools_memory = 0;
items_group_t *items_group;
uint32_t pool_items_size;
/* Recover memory_pools */
memory_pools = memory_pools_from_handler (memory_pools_handle);
statistics = malloc(memory_pools->pools_defined * 200);
printed_chars = sprintf (&statistics[0], "Pool: number, size, minimum, free\n");
printed_chars = sprintf (&statistics[0], "Pool: size, number, minimum, free, address space and memory used in Kbytes\n");
for (pool = 0; pool < memory_pools->pools_defined; pool++)
{
allocated_pool_memory = memory_pools->pools[pool].items_group_free.number * memory_pools->pools[pool].pool_item_size;
items_group = &memory_pools->pools[pool].items_group_free;
allocated_pool_memory = items_group_number_items (items_group) * memory_pools->pools[pool].pool_item_size;
allocated_pools_memory += allocated_pool_memory;
printed_chars += sprintf (&statistics[printed_chars], " %2u: %6u, %6lu, %6u, %6u, %6u Kbytes\n",
pool,
memory_pools->pools[pool].items_group_free.number,
memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t),
memory_pools->pools[pool].items_group_free.minimum + 1,
memory_pools->pools[pool].items_group_free.current + 1,
pool_items_size = memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t);
printed_chars += sprintf (&statistics[printed_chars], " %2u: %6u, %6u, %6u, %6u, [%p-%p] %6u\n",
pool, pool_items_size,
items_group_number_items (items_group),
items_group->minimum,
items_group_free_items (items_group),
memory_pools->pools[pool].items,
((void *) memory_pools->pools[pool].items) + allocated_pool_memory,
allocated_pool_memory / (1024));
}
printed_chars = sprintf (&statistics[printed_chars], "Pools memory %u Kbytes\n", allocated_pools_memory / (1024));
......@@ -350,27 +361,28 @@ int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t p
AssertFatal (pool_item_size <= MAX_POOL_ITEM_SIZE, "Item size is too big for memory pool items (%u/%d)\n", pool_item_size, MAX_POOL_ITEM_SIZE); /* Limit to a reasonable item size */
/* Recover memory_pools */
memory_pools = memory_pools_from_handler (memory_pools_handle);
memory_pools = memory_pools_from_handler (memory_pools_handle);
/* Check number of already created pools */
AssertFatal (memory_pools->pools_defined < memory_pools->pools_number, "Can not allocate more memory pool (%d)\n", memory_pools->pools_number);
/* Select pool */
pool = memory_pools->pools_defined;
memory_pool = &memory_pools->pools[pool];
pool = memory_pools->pools_defined;
memory_pool = &memory_pools->pools[pool];
/* Initialize pool */
{
memory_pool->pool_id = pool;
memory_pool->pool_id = pool;
/* Item size in memory_pool_data_t items by excess */
memory_pool->item_data_number = (pool_item_size + sizeof(memory_pool_data_t) - 1) / sizeof(memory_pool_data_t);
memory_pool->pool_item_size = (memory_pool->item_data_number * sizeof(memory_pool_data_t)) + sizeof(memory_pool_item_t);
memory_pool->items_group_free.number = pool_items_number;
memory_pool->items_group_free.current = pool_items_number - 1;
memory_pool->items_group_free.minimum = pool_items_number - 1;
memory_pool->item_data_number = (pool_item_size + sizeof(memory_pool_data_t) - 1) / sizeof(memory_pool_data_t);
memory_pool->pool_item_size = (memory_pool->item_data_number * sizeof(memory_pool_data_t)) + sizeof(memory_pool_item_t);
memory_pool->items_group_free.number_plus_one = pool_items_number + 1;
memory_pool->items_group_free.minimum = pool_items_number;
memory_pool->items_group_free.positions.ind.put = pool_items_number;
memory_pool->items_group_free.positions.ind.get = 0;
/* Allocate free indexes */
memory_pool->items_group_free.indexes = malloc(pool_items_number * sizeof(items_group_index_t));
memory_pool->items_group_free.indexes = malloc(memory_pool->items_group_free.number_plus_one * sizeof(items_group_index_t));
AssertFatal (memory_pool->items_group_free.indexes != NULL, "Memory pool indexes allocation failed\n");
/* Initialize free indexes */
......@@ -378,6 +390,8 @@ int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t p
{
memory_pool->items_group_free.indexes[item_index] = item_index;
}
/* Last index is not allocated */
memory_pool->items_group_free.indexes[item_index] = ITEMS_GROUP_INDEX_INVALID;
/* Allocate items */
memory_pool->items = calloc (pool_items_number, memory_pool->pool_item_size);
......@@ -451,7 +465,7 @@ memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_po
MP_DEBUG(" Alloc [%2u][%6d]{%6d}, %3u %3u, %6u, %p, %p, %p\n",
pool, item_index,
memory_pools->pools[pool].items_group_free.current,
items_group_free_items (&memory_pools->pools[pool].items_group_free),
info_0, info_1,
item_size,
memory_pools->pools[pool].items,
......@@ -500,11 +514,12 @@ void memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_i
pool_item_size = memory_pools->pools[pool].pool_item_size;
item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size;
MP_DEBUG(" Free [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %lu\n",
pool, item_index, memory_pools->pools[pool].items_group_free.current,
MP_DEBUG(" Free [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n",
pool, item_index,
items_group_free_items (&memory_pools->pools[pool].items_group_free),
memory_pool_item->start.info[0], info_1,
memory_pool_item_handle, memory_pool_item,
memory_pools->pools[pool].items, item_size * sizeof(memory_pool_data_t));
memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t))));
/* Sanity check on calculated item index */
AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index), "Incorrect memory pool item address (%p, %p) for pool %u, item %d\n",
......@@ -524,3 +539,52 @@ void memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_i
__sync_and_and_fetch (&vcd_mp_free, ~(1L << info_1)));
#endif
}
void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info)
{
memory_pools_t *memory_pools;
memory_pool_item_t *memory_pool_item;
pool_id_t pool;
items_group_index_t item_index;
uint32_t item_size;
uint32_t pool_item_size;
AssertFatal (index < MEMORY_POOL_ITEM_INFO_NUMBER, "Incorrect info index (%d/%d)\n", index, MEMORY_POOL_ITEM_INFO_NUMBER);
/* Recover memory pool item */
memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle);
/* Set info[1] */
memory_pool_item->start.info[index] = info;
/* Check item validity and log (not mandatory) */
if (1)
{
/* Recover memory_pools */
memory_pools = memory_pools_from_handler (memory_pools_handle);
/* Recover pool index */
pool = memory_pool_item->start.pool_id;
AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)\n", pool, memory_pools->pools_defined);
item_size = memory_pools->pools[pool].item_data_number;
pool_item_size = memory_pools->pools[pool].pool_item_size;
item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size;
MP_DEBUG(" Info [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n",
pool, item_index,
items_group_free_items (&memory_pools->pools[pool].items_group_free),
memory_pool_item->start.info[0], memory_pool_item->start.info[1],
memory_pool_item_handle, memory_pool_item,
memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t))));
/* Sanity check on calculated item index */
AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index), "Incorrect memory pool item address (%p, %p) for pool %u, item %d\n",
memory_pool_item, memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index);
/* Sanity check on end marker, must still be present (no write overflow) */
AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK, "Memory pool item is corrupted, end mark is not present for pool %u, item %d\n", pool, item_index);
/* Sanity check on item status, must be allocated */
AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED, "Trying to free a non allocated (%x) memory pool item (pool %u, item %d)\n",
memory_pool_item->start.item_status, pool, item_index);
}
}
......@@ -46,4 +46,6 @@ memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_po
void memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0);
void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info);
#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