From bf2371d272bac279db965abeca2c5979155d8cc3 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 15 Feb 2012 22:01:08 +0400 Subject: [PATCH] Add temporary pages to pool allocator to allow reset of some pool data. --- src/mem_pool.c | 121 +++++++++++++++++++++++++++++++++++++++++++------ src/mem_pool.h | 23 ++++++++++ 2 files changed, 130 insertions(+), 14 deletions(-) diff --git a/src/mem_pool.c b/src/mem_pool.c index 05f1bc690..c69cb0388 100644 --- a/src/mem_pool.c +++ b/src/mem_pool.c @@ -195,6 +195,8 @@ memory_pool_new (gsize size) new->cur_pool = pool_chain_new (size); new->shared_pool = NULL; new->first_pool = new->cur_pool; + new->cur_pool_tmp = NULL; + new->first_pool_tmp = NULL; new->destructors = NULL; /* Set it upon first call of set variable */ new->variables = NULL; @@ -209,8 +211,8 @@ memory_pool_new (gsize size) return new; } -void * -memory_pool_alloc (memory_pool_t * pool, gsize size) +static void * +memory_pool_alloc_common (memory_pool_t * pool, gsize size, gboolean is_tmp) { guint8 *tmp; struct _pool_chain *new, *cur; @@ -219,33 +221,68 @@ memory_pool_alloc (memory_pool_t * pool, gsize size) if (pool) { POOL_MTX_LOCK (); #ifdef MEMORY_GREEDY - cur = pool->first_pool; + if (is_tmp) { + cur = pool->first_pool_tmp; + } + else { + cur = pool->first_pool; + } #else - cur = pool->cur_pool; + if (is_tmp) { + cur = pool->cur_pool_tmp; + } + else { + cur = pool->cur_pool; + } #endif /* Find free space in pool chain */ - while ((free = pool_chain_free (cur)) < (gint)size && cur->next) { + while (cur != NULL && + (free = pool_chain_free (cur)) < (gint)size && + cur->next != NULL) { cur = cur->next; } - if (free < (gint)size && cur->next == NULL) { - /* Allocate new pool */ - if (cur->len >= size + MEM_ALIGNMENT) { - new = pool_chain_new (cur->len); + if (cur == NULL || (free < (gint)size && cur->next == NULL)) { + /* Allocate new pool */ + if (cur == NULL) { + if (pool->first_pool->len >= size + MEM_ALIGNMENT) { + new = pool_chain_new (pool->first_pool->len); + } + else { + new = pool_chain_new (size + pool->first_pool->len + MEM_ALIGNMENT); + } + /* Connect to pool subsystem */ + if (is_tmp) { + pool->first_pool_tmp = new; + } + else { + pool->first_pool = new; + } } else { - mem_pool_stat->oversized_chunks++; - new = pool_chain_new (size + pool->first_pool->len + MEM_ALIGNMENT); + if (cur->len >= size + MEM_ALIGNMENT) { + new = pool_chain_new (cur->len); + } + else { + mem_pool_stat->oversized_chunks++; + new = pool_chain_new (size + pool->first_pool->len + MEM_ALIGNMENT); + } + /* Attach new pool to chain */ + cur->next = new; + } + if (is_tmp) { + pool->cur_pool_tmp = new; + } + else { + pool->cur_pool = new; } - /* Attach new pool to chain */ - cur->next = new; - pool->cur_pool = new; /* No need to align again */ tmp = new->pos; new->pos = tmp + size; POOL_MTX_UNLOCK (); return tmp; } + /* No need to allocate page */ tmp = align_ptr (cur->pos, MEM_ALIGNMENT); cur->pos = tmp + size; POOL_MTX_UNLOCK (); @@ -254,6 +291,19 @@ memory_pool_alloc (memory_pool_t * pool, gsize size) return NULL; } + +void * +memory_pool_alloc (memory_pool_t * pool, gsize size) +{ + return memory_pool_alloc_common (pool, size, FALSE); +} + +void * +memory_pool_alloc_tmp (memory_pool_t * pool, gsize size) +{ + return memory_pool_alloc_common (pool, size, TRUE); +} + void * memory_pool_alloc0 (memory_pool_t * pool, gsize size) { @@ -264,6 +314,16 @@ memory_pool_alloc0 (memory_pool_t * pool, gsize size) return pointer; } +void * +memory_pool_alloc0_tmp (memory_pool_t * pool, gsize size) +{ + void *pointer = memory_pool_alloc_tmp (pool, size); + if (pointer) { + memset (pointer, 0, size); + } + return pointer; +} + void * memory_pool_alloc0_shared (memory_pool_t * pool, gsize size) { @@ -522,6 +582,18 @@ memory_pool_delete (memory_pool_t * pool) destructor = destructor->prev; } + while (cur) { + tmp = cur; + cur = cur->next; + STAT_LOCK (); + mem_pool_stat->chunks_freed++; + mem_pool_stat->bytes_allocated -= tmp->len; + STAT_UNLOCK (); + g_slice_free1 (tmp->len, tmp->begin); + g_slice_free (struct _pool_chain, tmp); + } + /* Clean temporary pools */ + cur = pool->first_pool_tmp; while (cur) { tmp = cur; cur = cur->next; @@ -551,6 +623,27 @@ memory_pool_delete (memory_pool_t * pool) g_slice_free (memory_pool_t, pool); } +void +memory_pool_cleanup_tmp (memory_pool_t* pool) +{ + struct _pool_chain *cur = pool->first_pool, *tmp; + + POOL_MTX_LOCK (); + cur = pool->first_pool_tmp; + while (cur) { + tmp = cur; + cur = cur->next; + STAT_LOCK (); + mem_pool_stat->chunks_freed++; + mem_pool_stat->bytes_allocated -= tmp->len; + STAT_UNLOCK (); + g_slice_free1 (tmp->len, tmp->begin); + g_slice_free (struct _pool_chain, tmp); + } + mem_pool_stat->pools_freed++; + POOL_MTX_UNLOCK (); +} + void memory_pool_stat (memory_pool_stat_t * st) { diff --git a/src/mem_pool.h b/src/mem_pool.h index 475a00629..970376a9a 100644 --- a/src/mem_pool.h +++ b/src/mem_pool.h @@ -73,6 +73,8 @@ struct _pool_destructors { typedef struct memory_pool_s { struct _pool_chain *cur_pool; /**< currently used page */ struct _pool_chain *first_pool; /**< first page */ + struct _pool_chain *cur_pool_tmp; /**< currently used temporary page */ + struct _pool_chain *first_pool_tmp; /**< first temporary page */ struct _pool_chain_shared *shared_pool; /**< shared chain */ struct _pool_destructors *destructors; /**< destructors chain */ GHashTable *variables; /**< private memory pool variables */ @@ -119,6 +121,14 @@ memory_pool_t* memory_pool_new (gsize size); */ void* memory_pool_alloc (memory_pool_t* pool, gsize size); +/** + * Get memory from temporary pool + * @param pool memory pool object + * @param size bytes to allocate + * @return pointer to allocated object + */ +void* memory_pool_alloc_tmp (memory_pool_t* pool, gsize size); + /** * Get memory and set it to zero * @param pool memory pool object @@ -127,6 +137,19 @@ void* memory_pool_alloc (memory_pool_t* pool, gsize size); */ void* memory_pool_alloc0 (memory_pool_t* pool, gsize size); +/** + * Get memory and set it to zero + * @param pool memory pool object + * @param size bytes to allocate + * @return pointer to allocated object + */ +void* memory_pool_alloc0_tmp (memory_pool_t* pool, gsize size); + +/** + * Cleanup temporary data in pool + */ +void memory_pool_cleanup_tmp (memory_pool_t* pool); + /** * Make a copy of string in pool * @param pool memory pool object -- 2.39.5