summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2012-02-15 22:01:08 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2012-02-15 22:01:08 +0400
commitbf2371d272bac279db965abeca2c5979155d8cc3 (patch)
tree4f23ecda9c5d6c886e864051d884b06e4ef067ce
parent384d3c358c36b8649b3ec829887dcb99d0d1f2cf (diff)
downloadrspamd-bf2371d272bac279db965abeca2c5979155d8cc3.tar.gz
rspamd-bf2371d272bac279db965abeca2c5979155d8cc3.zip
Add temporary pages to pool allocator to allow reset of some pool data.
-rw-r--r--src/mem_pool.c121
-rw-r--r--src/mem_pool.h23
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)
{
@@ -265,6 +315,16 @@ memory_pool_alloc0 (memory_pool_t * pool, gsize size)
}
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)
{
void *pointer = memory_pool_alloc_shared (pool, size);
@@ -532,6 +592,18 @@ memory_pool_delete (memory_pool_t * pool)
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;
+ 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);
+ }
/* Unmap shared memory */
while (cur_shared) {
tmp_shared = cur_shared;
@@ -552,6 +624,27 @@ memory_pool_delete (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)
{
st->pools_allocated = mem_pool_stat->pools_allocated;
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 */
@@ -120,6 +122,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
* @param size bytes to allocate
@@ -128,6 +138,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
* @param src source string