]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Start reworking of the mempool structure
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 23 Dec 2019 15:14:02 +0000 (15:14 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 23 Dec 2019 15:14:02 +0000 (15:14 +0000)
- Hide implementation details
- Pre-allocate one chain on start
- Organize destructors as a list of structures
- Use posix_memalign instead of malloc
- Adjust allocation layout

src/libserver/task.c
src/libutil/mem_pool.c
src/libutil/mem_pool.h
src/libutil/mem_pool_internal.h [new file with mode: 0644]

index 7cdce32f3da34ed7751679dc70f192cb4f98b2c9..e7aab0f8219d2520048fd522e4b392630590809b 100644 (file)
@@ -1547,13 +1547,13 @@ rspamd_task_log_variable (struct rspamd_task *task,
        case RSPAMD_LOG_MEMPOOL_SIZE:
                var.len = rspamd_snprintf (numbuf, sizeof (numbuf),
                                "%Hz",
-                               task->task_pool->used_memory);
+                               rspamd_mempool_get_used_size (task->task_pool));
                var.begin = numbuf;
                break;
        case RSPAMD_LOG_MEMPOOL_WASTE:
                var.len = rspamd_snprintf (numbuf, sizeof (numbuf),
                                "%Hz",
-                               task->task_pool->wasted_memory);
+                               rspamd_mempool_get_wasted_size (task->task_pool));
                var.begin = numbuf;
                break;
        default:
index ed3a6b73d8e407fd11e1c296362a587121aa82d7..c6a5a4900ef3bf3acae645f881ef51bb4a3cf655 100644 (file)
@@ -22,6 +22,7 @@
 #include "khash.h"
 #include "cryptobox.h"
 #include "contrib/uthash/utlist.h"
+#include "mem_pool_internal.h"
 
 #ifdef WITH_JEMALLOC
 #include <jemalloc/jemalloc.h>
 #undef MEMORY_GREEDY
 
 
-#define ENTRY_LEN 128
-#define ENTRY_NELTS 64
-
-struct entry_elt {
-       guint32 fragmentation;
-       guint32 leftover;
-};
-
-struct rspamd_mempool_entry_point {
-       gchar src[ENTRY_LEN];
-       guint32 cur_suggestion;
-       guint32 cur_elts;
-       struct entry_elt elts[ENTRY_NELTS];
-};
-
-
 static inline uint32_t
 rspamd_entry_hash (const char *str)
 {
@@ -233,11 +218,11 @@ rspamd_mempool_chain_new (gsize size, enum rspamd_mempool_chain_type pool_type)
                optimal_size = sys_alloc_size (total_size);
 #endif
                total_size = MAX (total_size, optimal_size);
-               map = malloc (total_size);
+               gint ret = posix_memalign (&map, MIN_MEM_ALIGNMENT, total_size);
 
-               if (map == NULL) {
-                       g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
-                                       G_STRLOC, total_size);
+               if (ret != 0 || map == NULL) {
+                       g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes: %d - %s",
+                                       G_STRLOC, total_size, ret, strerror (errno));
                        abort ();
                }
 
@@ -268,7 +253,7 @@ rspamd_mempool_get_chain (rspamd_mempool_t * pool,
 {
        g_assert (pool_type >= 0 && pool_type < RSPAMD_MEMPOOL_MAX);
 
-       return pool->pools[pool_type];
+       return pool->priv->pools[pool_type];
 }
 
 static void
@@ -279,7 +264,7 @@ rspamd_mempool_append_chain (rspamd_mempool_t * pool,
        g_assert (pool_type >= 0 && pool_type < RSPAMD_MEMPOOL_MAX);
        g_assert (chain != NULL);
 
-       LL_PREPEND (pool->pools[pool_type], chain);
+       LL_PREPEND (pool->priv->pools[pool_type], chain);
 }
 
 /**
@@ -345,19 +330,48 @@ rspamd_mempool_new_ (gsize size, const gchar *tag, const gchar *loc)
                env_checked = TRUE;
        }
 
-       new_pool = g_malloc0 (sizeof (rspamd_mempool_t));
-       new_pool->entry = rspamd_mempool_get_entry (loc);
-       new_pool->destructors = g_array_sized_new (FALSE, FALSE,
-                       sizeof (struct _pool_destructors), 32);
-       /* Set it upon first call of set variable */
+       struct rspamd_mempool_entry_point *entry = rspamd_mempool_get_entry (loc);
+       gsize total_size;
 
        if (size == 0) {
-               new_pool->elt_len = new_pool->entry->cur_suggestion;
+               size = entry->cur_suggestion;
        }
-       else {
-               new_pool->elt_len = size;
+
+       total_size = sizeof (rspamd_mempool_t) +
+                                sizeof (struct rspamd_mempool_specific) +
+                                MIN_MEM_ALIGNMENT +
+                                sizeof (struct _pool_chain) +
+                                size;
+
+       /*
+        * Memory layout:
+        * struct rspamd_mempool_t
+        * struct rspamd_mempool_specific
+        * struct _pool_chain
+        * alignment (if needed)
+        * memory chunk
+        */
+       guchar *mem_chunk;
+       gint ret = posix_memalign ((void **)&mem_chunk, MIN_MEM_ALIGNMENT,
+                       total_size);
+
+       if (ret != 0 || mem_chunk == NULL) {
+               g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes: %d - %s",
+                               G_STRLOC, total_size, ret, strerror (errno));
+               abort ();
        }
 
+       /* Set memory layout */
+       new_pool = (rspamd_mempool_t *)mem_chunk;
+       new_pool->priv = (struct rspamd_mempool_specific *)(mem_chunk +
+                       sizeof (rspamd_mempool_t));
+       memset (new_pool->priv, 0, sizeof (struct rspamd_mempool_specific) +
+                       sizeof (struct _pool_chain));
+
+       new_pool->priv->entry = rspamd_mempool_get_entry (loc);
+
+       new_pool->priv->elt_len = size;
+
        if (tag) {
                rspamd_strlcpy (new_pool->tag.tagname, tag, sizeof (new_pool->tag.tagname));
        }
@@ -375,6 +389,29 @@ rspamd_mempool_new_ (gsize size, const gchar *tag, const gchar *loc)
 
        mem_pool_stat->pools_allocated++;
 
+       /* Now we can attach one chunk to speed up simple allocations */
+       struct _pool_chain *nchain;
+
+       nchain = (struct _pool_chain *)mem_chunk + sizeof (rspamd_mempool_t) +
+                       sizeof (struct rspamd_mempool_specific);
+       nchain->slice_size = size;
+
+       guchar *unaligned = mem_chunk +
+                                               sizeof (rspamd_mempool_t) +
+                                               sizeof (struct rspamd_mempool_specific) +
+                                               sizeof (struct _pool_chain);
+
+       nchain->begin = align_ptr (unaligned, MIN_MEM_ALIGNMENT);
+       nchain->slice_size = size;
+       nchain->pos = nchain->begin;
+       new_pool->priv->pools[RSPAMD_MEMPOOL_NORMAL] = nchain;
+       new_pool->priv->used_memory = size;
+
+       /* Adjust stats */
+       g_atomic_int_add (&mem_pool_stat->bytes_allocated,
+                       (gint)size);
+       g_atomic_int_add (&mem_pool_stat->chunks_allocated, 1);
+
        return new_pool;
 }
 
@@ -393,7 +430,7 @@ memory_pool_alloc_common (rspamd_mempool_t * pool, gsize size,
 
        if (pool) {
                POOL_MTX_LOCK ();
-               pool->used_memory += size;
+               pool->priv->used_memory += size;
 
                if (always_malloc && pool_type != RSPAMD_MEMPOOL_SHARED) {
                        void *ptr;
@@ -401,11 +438,11 @@ memory_pool_alloc_common (rspamd_mempool_t * pool, gsize size,
                        ptr = g_malloc (size);
                        POOL_MTX_UNLOCK ();
 
-                       if (pool->trash_stack == NULL) {
-                               pool->trash_stack = g_ptr_array_sized_new (128);
+                       if (pool->priv->trash_stack == NULL) {
+                               pool->priv->trash_stack = g_ptr_array_sized_new (128);
                        }
 
-                       g_ptr_array_add (pool->trash_stack, ptr);
+                       g_ptr_array_add (pool->priv->trash_stack, ptr);
 
                        return ptr;
                }
@@ -419,21 +456,21 @@ memory_pool_alloc_common (rspamd_mempool_t * pool, gsize size,
 
                if (cur == NULL || free < size) {
                        if (free < size) {
-                               pool->wasted_memory += free;
+                               pool->priv->wasted_memory += free;
                        }
 
                        /* Allocate new chain element */
-                       if (pool->elt_len >= size + MIN_MEM_ALIGNMENT) {
-                               pool->entry->elts[pool->entry->cur_elts].fragmentation += size;
-                               new = rspamd_mempool_chain_new (pool->elt_len,
+                       if (pool->priv->elt_len >= size + MIN_MEM_ALIGNMENT) {
+                               pool->priv->entry->elts[pool->priv->entry->cur_elts].fragmentation += size;
+                               new = rspamd_mempool_chain_new (pool->priv->elt_len,
                                                pool_type);
                        }
                        else {
                                mem_pool_stat->oversized_chunks++;
                                g_atomic_int_add (&mem_pool_stat->fragmented_size,
                                                free);
-                               pool->entry->elts[pool->entry->cur_elts].fragmentation += free;
-                               new = rspamd_mempool_chain_new (size + pool->elt_len, pool_type);
+                               pool->priv->entry->elts[pool->priv->entry->cur_elts].fragmentation += free;
+                               new = rspamd_mempool_chain_new (size + pool->priv->elt_len, pool_type);
                        }
 
                        /* Connect to pool subsystem */
@@ -464,12 +501,6 @@ rspamd_mempool_alloc (rspamd_mempool_t * pool, gsize size)
        return memory_pool_alloc_common (pool, size, RSPAMD_MEMPOOL_NORMAL);
 }
 
-void *
-rspamd_mempool_alloc_tmp (rspamd_mempool_t * pool, gsize size)
-{
-       return memory_pool_alloc_common (pool, size, RSPAMD_MEMPOOL_TMP);
-}
-
 void *
 rspamd_mempool_alloc0 (rspamd_mempool_t * pool, gsize size)
 {
@@ -479,17 +510,6 @@ rspamd_mempool_alloc0 (rspamd_mempool_t * pool, gsize size)
 
        return pointer;
 }
-
-void *
-rspamd_mempool_alloc0_tmp (rspamd_mempool_t * pool, gsize size)
-{
-       void *pointer = rspamd_mempool_alloc_tmp (pool, size);
-
-       memset (pointer, 0, size);
-
-       return pointer;
-}
-
 void *
 rspamd_mempool_alloc0_shared (rspamd_mempool_t * pool, gsize size)
 {
@@ -563,15 +583,25 @@ rspamd_mempool_add_destructor_full (rspamd_mempool_t * pool,
        const gchar *function,
        const gchar *line)
 {
-       struct _pool_destructors cur;
+       struct _pool_destructors *cur;
 
        POOL_MTX_LOCK ();
-       cur.func = func;
-       cur.data = data;
-       cur.function = function;
-       cur.loc = line;
+       cur = rspamd_mempool_alloc (pool, sizeof (*cur));
+       cur->func = func;
+       cur->data = data;
+       cur->function = function;
+       cur->loc = line;
+       cur->next = NULL;
+
+       if (pool->priv->dtors_tail) {
+               pool->priv->dtors_tail->next = cur;
+               pool->priv->dtors_tail = cur;
+       }
+       else {
+               pool->priv->dtors_head = cur;
+               pool->priv->dtors_tail = cur;
+       }
 
-       g_array_append_val (pool->destructors, cur);
        POOL_MTX_UNLOCK ();
 }
 
@@ -582,11 +612,8 @@ rspamd_mempool_replace_destructor (rspamd_mempool_t * pool,
        void *new_data)
 {
        struct _pool_destructors *tmp;
-       guint i;
-
-       for (i = 0; i < pool->destructors->len; i ++) {
-               tmp = &g_array_index (pool->destructors, struct _pool_destructors, i);
 
+       LL_FOREACH (pool->priv->dtors_head, tmp) {
                if (tmp->func == func && tmp->data == old_data) {
                        tmp->func = func;
                        tmp->data = new_data;
@@ -621,11 +648,7 @@ rspamd_mempool_adjust_entry (struct rspamd_mempool_entry_point *e)
        sel_pos = sz[50 + jitter];
        sel_neg = sz[4 + jitter];
 
-       if (sel_neg > 0) {
-               /* We need to increase our suggestion */
-               e->cur_suggestion *= (1 + (((double)sel_pos) / e->cur_suggestion)) * 1.5;
-       }
-       else if (-sel_neg > sel_pos) {
+       if (-sel_neg > sel_pos) {
                /* We need to reduce current suggestion */
                e->cur_suggestion /= (1 + (((double)-sel_neg) / e->cur_suggestion)) * 1.5;
        }
@@ -649,19 +672,17 @@ void
 rspamd_mempool_destructors_enforce (rspamd_mempool_t *pool)
 {
        struct _pool_destructors *destructor;
-       guint i;
 
        POOL_MTX_LOCK ();
 
-       for (i = 0; i < pool->destructors->len; i ++) {
-               destructor = &g_array_index (pool->destructors, struct _pool_destructors, i);
+       LL_FOREACH (pool->priv->dtors_head, destructor) {
                /* Avoid calling destructors for NULL pointers */
                if (destructor->data != NULL) {
                        destructor->func (destructor->data);
                }
        }
 
-       pool->destructors->len = 0;
+       pool->priv->dtors_head = pool->priv->dtors_tail = NULL;
 
        POOL_MTX_UNLOCK ();
 }
@@ -679,36 +700,33 @@ rspamd_mempool_delete (rspamd_mempool_t * pool)
 
        cur = NULL;
 
-       if (pool->pools[RSPAMD_MEMPOOL_NORMAL] != NULL) {
-               cur = pool->pools[RSPAMD_MEMPOOL_NORMAL];
+       if (pool->priv->pools[RSPAMD_MEMPOOL_NORMAL] != NULL) {
+               cur = pool->priv->pools[RSPAMD_MEMPOOL_NORMAL];
        }
 
        if (cur && mempool_entries) {
-               pool->entry->elts[pool->entry->cur_elts].leftover =
+               pool->priv->entry->elts[pool->priv->entry->cur_elts].leftover =
                                pool_chain_free (cur);
 
-               pool->entry->cur_elts = (pool->entry->cur_elts + 1) %
-                               G_N_ELEMENTS (pool->entry->elts);
+               pool->priv->entry->cur_elts = (pool->priv->entry->cur_elts + 1) %
+                               G_N_ELEMENTS (pool->priv->entry->elts);
 
-               if (pool->entry->cur_elts == 0) {
-                       rspamd_mempool_adjust_entry (pool->entry);
+               if (pool->priv->entry->cur_elts == 0) {
+                       rspamd_mempool_adjust_entry (pool->priv->entry);
                }
        }
 
        /* Call all pool destructors */
-       for (i = 0; i < pool->destructors->len; i ++) {
-               destructor = &g_array_index (pool->destructors, struct _pool_destructors, i);
+       LL_FOREACH (pool->priv->dtors_head, destructor) {
                /* Avoid calling destructors for NULL pointers */
                if (destructor->data != NULL) {
                        destructor->func (destructor->data);
                }
        }
 
-       g_array_free (pool->destructors, TRUE);
-
-       for (i = 0; i < G_N_ELEMENTS (pool->pools); i ++) {
-               if (pool->pools[i]) {
-                       LL_FOREACH_SAFE (pool->pools[i], cur, tmp) {
+       for (i = 0; i < G_N_ELEMENTS (pool->priv->pools); i ++) {
+               if (pool->priv->pools[i]) {
+                       LL_FOREACH_SAFE (pool->priv->pools[i], cur, tmp) {
                                g_atomic_int_add (&mem_pool_stat->bytes_allocated,
                                                -((gint)cur->slice_size));
                                g_atomic_int_add (&mem_pool_stat->chunks_allocated, -1);
@@ -725,17 +743,17 @@ rspamd_mempool_delete (rspamd_mempool_t * pool)
                }
        }
 
-       if (pool->variables) {
-               g_hash_table_destroy (pool->variables);
+       if (pool->priv->variables) {
+               g_hash_table_destroy (pool->priv->variables);
        }
 
-       if (pool->trash_stack) {
-               for (i = 0; i < pool->trash_stack->len; i++) {
-                       ptr = g_ptr_array_index (pool->trash_stack, i);
+       if (pool->priv->trash_stack) {
+               for (i = 0; i < pool->priv->trash_stack->len; i++) {
+                       ptr = g_ptr_array_index (pool->priv->trash_stack, i);
                        g_free (ptr);
                }
 
-               g_ptr_array_free (pool->trash_stack, TRUE);
+               g_ptr_array_free (pool->priv->trash_stack, TRUE);
        }
 
        g_atomic_int_inc (&mem_pool_stat->pools_freed);
@@ -743,29 +761,6 @@ rspamd_mempool_delete (rspamd_mempool_t * pool)
        g_free (pool);
 }
 
-void
-rspamd_mempool_cleanup_tmp (rspamd_mempool_t * pool)
-{
-       struct _pool_chain *cur, *tmp;
-
-       POOL_MTX_LOCK ();
-
-       if (pool->pools[RSPAMD_MEMPOOL_TMP]) {
-               LL_FOREACH_SAFE (pool->pools[RSPAMD_MEMPOOL_TMP], cur, tmp) {
-                       g_atomic_int_add (&mem_pool_stat->bytes_allocated,
-                                       -((gint)cur->slice_size));
-                       g_atomic_int_add (&mem_pool_stat->chunks_allocated, -1);
-
-                       free (cur);
-               }
-
-               pool->pools[RSPAMD_MEMPOOL_TMP] = NULL;
-       }
-
-       g_atomic_int_inc (&mem_pool_stat->pools_freed);
-       POOL_MTX_UNLOCK ();
-}
-
 void
 rspamd_mempool_stat (rspamd_mempool_stat_t * st)
 {
@@ -1015,11 +1010,11 @@ rspamd_mempool_set_variable (rspamd_mempool_t *pool,
        gpointer value,
        rspamd_mempool_destruct_t destructor)
 {
-       if (pool->variables == NULL) {
-               pool->variables = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
+       if (pool->priv->variables == NULL) {
+               pool->priv->variables = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
        }
 
-       g_hash_table_insert (pool->variables, rspamd_mempool_strdup (pool,
+       g_hash_table_insert (pool->priv->variables, rspamd_mempool_strdup (pool,
                name), value);
        if (destructor != NULL) {
                rspamd_mempool_add_destructor (pool, destructor, value);
@@ -1029,18 +1024,18 @@ rspamd_mempool_set_variable (rspamd_mempool_t *pool,
 gpointer
 rspamd_mempool_get_variable (rspamd_mempool_t *pool, const gchar *name)
 {
-       if (pool->variables == NULL) {
+       if (pool->priv->variables == NULL) {
                return NULL;
        }
 
-       return g_hash_table_lookup (pool->variables, name);
+       return g_hash_table_lookup (pool->priv->variables, name);
 }
 
 void
 rspamd_mempool_remove_variable (rspamd_mempool_t *pool, const gchar *name)
 {
-       if (pool->variables != NULL) {
-               g_hash_table_remove (pool->variables, name);
+       if (pool->priv->variables != NULL) {
+               g_hash_table_remove (pool->priv->variables, name);
        }
 }
 
@@ -1085,3 +1080,15 @@ rspamd_mempool_glist_append (rspamd_mempool_t *pool, GList *l, gpointer p)
 
        return l;
 }
+
+gsize
+rspamd_mempool_get_used_size (rspamd_mempool_t *pool)
+{
+       return pool->priv->used_memory;
+}
+
+gsize
+rspamd_mempool_get_wasted_size (rspamd_mempool_t *pool)
+{
+       return pool->priv->wasted_memory;
+}
\ No newline at end of file
index a32aa0597612ab73ff5aa7ef501489ba8f4254c0..75e949985673067983f54d13fda0f6615859139b 100644 (file)
@@ -1,3 +1,19 @@
+/*-
+ * Copyright 2019 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 /**
  * @file mem_pool.h
  * \brief Memory pools library.
@@ -50,17 +66,8 @@ struct f_str_s;
 
 #define MEMPOOL_TAG_LEN 20
 #define MEMPOOL_UID_LEN 20
+/* All pointers are aligned as this variable */
 #define MIN_MEM_ALIGNMENT   sizeof (guint64)
-#define align_ptr(p, a)                                                   \
-    (guint8 *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
-
-enum rspamd_mempool_chain_type {
-       RSPAMD_MEMPOOL_NORMAL = 0,
-       RSPAMD_MEMPOOL_TMP,
-       RSPAMD_MEMPOOL_SHARED,
-       RSPAMD_MEMPOOL_MAX
-};
-
 /**
  * Destructor type definition
  */
@@ -87,27 +94,6 @@ typedef pthread_mutex_t rspamd_mempool_mutex_t;
 typedef pthread_rwlock_t rspamd_mempool_rwlock_t;
 #endif
 
-/**
- * Pool page structure
- */
-struct _pool_chain {
-       guint8 *begin;                  /**< begin of pool chain block              */
-       guint8 *pos;                    /**< current start of free space in block   */
-       gsize slice_size;                      /**< length of block                        */
-       rspamd_mempool_mutex_t *lock;
-       struct _pool_chain *next;
-};
-
-/**
- * Destructors list item structure
- */
-struct _pool_destructors {
-       rspamd_mempool_destruct_t func;         /**< pointer to destructor                                      */
-       void *data;                             /**< data to free                                                       */
-       const gchar *function;                  /**< function from which this destructor was added */
-       const gchar *loc;                       /**< line number                            */
-};
-
 /**
  * Tag to use for logging purposes
  */
@@ -116,20 +102,18 @@ struct rspamd_mempool_tag {
        gchar uid[MEMPOOL_UID_LEN];             /**< unique id                                                          */
 };
 
+enum rspamd_mempool_flags {
+       RSPAMD_MEMPOOL_DEBUG = (1u << 0u),
+};
+
 /**
  * Memory pool type
  */
 struct rspamd_mempool_entry_point;
 struct rspamd_mutex_s;
+struct rspamd_mempool_specific;
 typedef struct memory_pool_s {
-       struct _pool_chain *pools[RSPAMD_MEMPOOL_MAX];
-       GArray *destructors;
-       GPtrArray *trash_stack;
-       GHashTable *variables;                  /**< private memory pool variables                      */
-       gsize elt_len;                            /**< size of an element                                               */
-       gsize used_memory;
-       gsize wasted_memory;
-       struct rspamd_mempool_entry_point *entry;
+       struct rspamd_mempool_specific *priv;
        struct rspamd_mempool_tag tag;          /**< memory pool tag                                            */
 } rspamd_mempool_t;
 
@@ -166,14 +150,6 @@ rspamd_mempool_t *rspamd_mempool_new_ (gsize size, const gchar *tag, const gchar
 void *rspamd_mempool_alloc (rspamd_mempool_t *pool, gsize size)
 RSPAMD_ATTR_ALLOC_SIZE(2) RSPAMD_ATTR_ALLOC_ALIGN(MIN_MEM_ALIGNMENT) RSPAMD_ATTR_RETURNS_NONNUL;
 
-/**
- * Get memory from temporary pool
- * @param pool memory pool object
- * @param size bytes to allocate
- * @return pointer to allocated object
- */
-void *rspamd_mempool_alloc_tmp (rspamd_mempool_t *pool, gsize size) RSPAMD_ATTR_RETURNS_NONNUL;
-
 /**
  * Get memory and set it to zero
  * @param pool memory pool object
@@ -183,19 +159,6 @@ void *rspamd_mempool_alloc_tmp (rspamd_mempool_t *pool, gsize size) RSPAMD_ATTR_
 void *rspamd_mempool_alloc0 (rspamd_mempool_t *pool, gsize size)
 RSPAMD_ATTR_ALLOC_SIZE(2) RSPAMD_ATTR_ALLOC_ALIGN(MIN_MEM_ALIGNMENT) RSPAMD_ATTR_RETURNS_NONNUL;
 
-/**
- * Get memory and set it to zero
- * @param pool memory pool object
- * @param size bytes to allocate
- * @return pointer to allocated object
- */
-void *rspamd_mempool_alloc0_tmp (rspamd_mempool_t *pool, gsize size) RSPAMD_ATTR_RETURNS_NONNUL;
-
-/**
- * Cleanup temporary data in pool
- */
-void rspamd_mempool_cleanup_tmp (rspamd_mempool_t *pool);
-
 /**
  * Make a copy of string in pool
  * @param pool memory pool object
@@ -344,6 +307,9 @@ void rspamd_mempool_stat_reset (void);
 
 gsize rspamd_mempool_suggest_size_ (const char *loc);
 
+gsize rspamd_mempool_get_used_size (rspamd_mempool_t *pool);
+gsize rspamd_mempool_get_wasted_size (rspamd_mempool_t *pool);
+
 /**
  * Set memory pool variable
  * @param pool memory pool object
@@ -351,8 +317,10 @@ gsize rspamd_mempool_suggest_size_ (const char *loc);
  * @param gpointer value value of variable
  * @param destructor pointer to function-destructor
  */
-void rspamd_mempool_set_variable (rspamd_mempool_t *pool, const gchar *name,
-                                                                 gpointer value, rspamd_mempool_destruct_t destructor);
+void rspamd_mempool_set_variable (rspamd_mempool_t *pool,
+                                                                 const gchar *name,
+                                                                 gpointer value,
+                                                                 rspamd_mempool_destruct_t destructor);
 
 /**
  * Get memory pool variable
diff --git a/src/libutil/mem_pool_internal.h b/src/libutil/mem_pool_internal.h
new file mode 100644 (file)
index 0000000..9341fce
--- /dev/null
@@ -0,0 +1,81 @@
+/*-
+ * Copyright 2019 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSPAMD_MEM_POOL_INTERNAL_H
+#define RSPAMD_MEM_POOL_INTERNAL_H
+
+/*
+ * Internal memory pool stuff
+ */
+
+#define align_ptr(p, a)                                                   \
+    (guint8 *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
+
+enum rspamd_mempool_chain_type {
+       RSPAMD_MEMPOOL_NORMAL = 0,
+       RSPAMD_MEMPOOL_SHARED,
+       RSPAMD_MEMPOOL_MAX
+};
+#define ENTRY_LEN 128
+#define ENTRY_NELTS 64
+
+struct entry_elt {
+       guint32 fragmentation;
+       guint32 leftover;
+};
+
+struct rspamd_mempool_entry_point {
+       gchar src[ENTRY_LEN];
+       guint32 cur_suggestion;
+       guint32 cur_elts;
+       struct entry_elt elts[ENTRY_NELTS];
+};
+
+/**
+ * Destructors list item structure
+ */
+struct _pool_destructors {
+       rspamd_mempool_destruct_t func;         /**< pointer to destructor                                      */
+       void *data;                             /**< data to free                                                       */
+       const gchar *function;                  /**< function from which this destructor was added */
+       const gchar *loc;                       /**< line number                            */
+       struct _pool_destructors *next;
+};
+
+struct rspamd_mempool_specific {
+       struct _pool_chain *pools[RSPAMD_MEMPOOL_MAX];
+       struct _pool_destructors *dtors_head, *dtors_tail;
+       GPtrArray *trash_stack;
+       GHashTable *variables;                  /**< private memory pool variables                      */
+       gsize elt_len;                            /**< size of an element                                               */
+       gsize used_memory;
+       gsize wasted_memory;
+       struct rspamd_mempool_entry_point *entry;
+};
+
+/**
+ * Pool page structure
+ */
+struct _pool_chain {
+       guint8 *begin;                  /**< begin of pool chain block              */
+       guint8 *pos;                    /**< current start of free space in block   */
+       gsize slice_size;                      /**< length of block                        */
+       rspamd_mempool_mutex_t *lock;
+       struct _pool_chain *next;
+};
+
+
+#endif