jeyzu pushed a commit to branch master.
commit f253cfc12c27118e6516f6fec5d56922de119db8
Author: Jérémy Zurcher <[email protected]>
Date: Fri May 17 10:35:16 2013 +0200
eo ptr ind: empty tables are freed except 1 kept as spare
- this reduces unused memory usage
- the spare table avoids the free/alloc corner case
---
src/lib/eo/eo_ptr_indirection.c | 45 +++++++++++++++++++++++++++++++++++------
1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/src/lib/eo/eo_ptr_indirection.c b/src/lib/eo/eo_ptr_indirection.c
index bb466da..4dc768b 100644
--- a/src/lib/eo/eo_ptr_indirection.c
+++ b/src/lib/eo/eo_ptr_indirection.c
@@ -22,7 +22,7 @@
* - a tree structure is used, composed of a top level table pointing at
* mid tables pointing at tables composed of entries.
* - tables are allocated when needed (i.e no more empty entries in allocated
tables.
- * For now there is no mechanism to free empty tables.
+ * - empty tables are freed, except one kept as spare table.
*
* An Eo id is contructed by bits manipulation of table indexes and a
generation.
*
@@ -69,7 +69,7 @@
# define BITS_ENTRY_ID 12
# define BITS_GENERATION_COUNTER 10
# define DROPPED_TABLES 0
-# define DROPPED_ENTRIES 3
+# define DROPPED_ENTRIES 4
typedef int16_t Table_Index;
typedef uint16_t Generation_Counter;
#else
@@ -79,7 +79,7 @@ typedef uint16_t Generation_Counter;
# define BITS_ENTRY_ID 12
# define BITS_GENERATION_COUNTER 30
# define DROPPED_TABLES 2
-# define DROPPED_ENTRIES 2
+# define DROPPED_ENTRIES 3
typedef int16_t Table_Index;
typedef uint32_t Generation_Counter;
#endif
@@ -214,6 +214,8 @@ typedef struct
Table_Index fifo_tail;
/* Packed mid table and table indexes */
Eo_Id partial_id;
+ /* Counter of free entries */
+ unsigned int free_entries;
/* Entries of the table holding real pointers and generations */
_Eo_Id_Entry entries[MAX_ENTRY_ID];
} _Eo_Ids_Table;
@@ -224,6 +226,9 @@ static _Eo_Ids_Table **_eo_ids_tables[MAX_MID_TABLE_ID] = {
NULL };
/* Current table used for following allocations */
static _Eo_Ids_Table *_current_table = NULL;
+/* Spare empty table */
+static _Eo_Ids_Table *_empty_table = NULL;
+
/* Next generation to use when assigning a new entry to a Eo pointer */
Generation_Counter _eo_generation_counter = 0;
@@ -285,6 +290,7 @@ _get_available_entry(_Eo_Ids_Table *table)
entry = &(table->entries[table->start]);
UNPROTECT(table);
table->start++;
+ table->free_entries--;
}
else if (table->fifo_head != -1)
{
@@ -295,6 +301,7 @@ _get_available_entry(_Eo_Ids_Table *table)
table->fifo_head = table->fifo_tail = -1;
else
table->fifo_head = entry->next_in_fifo;
+ table->free_entries--;
}
return entry;
@@ -320,9 +327,20 @@ _search_tables()
if (!table)
{
- /* Allocate a new table and reserve the first entry */
- table = _eo_id_mem_calloc(1, sizeof(_Eo_Ids_Table));
+ if (_empty_table)
+ {
+ /* Recycle the available empty table */
+ table = _empty_table;
+ _empty_table = NULL;
+ UNPROTECT(table);
+ }
+ else
+ {
+ /* Allocate a new one and reserve the first entry */
+ table = _eo_id_mem_calloc(1, sizeof(_Eo_Ids_Table));
+ }
table->start = 1;
+ table->free_entries = MAX_ENTRY_ID - 1;
table->fifo_head = table->fifo_tail = -1;
table->partial_id = EO_COMPOSE_PARTIAL_ID(mid_table_id,
table_id);
entry = &(table->entries[0]);
@@ -397,6 +415,7 @@ _eo_id_release(const Eo_Id obj_id)
if (entry && entry->active && (entry->generation == generation))
{
UNPROTECT(table);
+ table->free_entries++;
/* Disable the entry */
entry->active = 0;
entry->next_in_fifo = -1;
@@ -411,6 +430,19 @@ _eo_id_release(const Eo_Id obj_id)
table->fifo_tail = entry_id;
}
PROTECT(table);
+ if (table->free_entries == MAX_ENTRY_ID)
+ {
+ UNPROTECT(_eo_ids_tables[mid_table_id]);
+ TABLE_FROM_IDS = NULL;
+ PROTECT(_eo_ids_tables[mid_table_id]);
+ /* Recycle or free the empty table */
+ if (!_empty_table)
+ _empty_table = table;
+ else
+ _eo_id_mem_free(table);
+ if (_current_table == table)
+ _current_table = NULL;
+ }
return;
}
}
@@ -439,7 +471,8 @@ _eo_free_ids_tables()
}
_eo_ids_tables[mid_table_id] = NULL;
}
- _current_table = NULL;
+ if (_empty_table) _eo_id_mem_free(_empty_table);
+ _empty_table = _current_table = NULL;
}
#ifdef EFL_DEBUG
--
------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d