aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-08-21 20:40:01 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-08-21 20:40:01 +0100
commit749330a61b23580a87cf223ea40a21f8b28b9225 (patch)
tree95ff0b4917ae83e3c66c5f9fbf33fe465c000a64
parent7f209537e7bf5081a6e94c4a7b3588ae6f6b4a7d (diff)
downloadrspamd-749330a61b23580a87cf223ea40a21f8b28b9225.tar.gz
rspamd-749330a61b23580a87cf223ea40a21f8b28b9225.zip
[Rework] Start mempool fragmentation reduce project
-rw-r--r--src/libutil/mem_pool.c94
-rw-r--r--src/libutil/mem_pool.h8
2 files changed, 96 insertions, 6 deletions
diff --git a/src/libutil/mem_pool.c b/src/libutil/mem_pool.c
index b5cfae311..692bfbf79 100644
--- a/src/libutil/mem_pool.c
+++ b/src/libutil/mem_pool.c
@@ -19,6 +19,8 @@
#include "logger.h"
#include "ottery.h"
#include "unix-std.h"
+#include "khash.h"
+#include "cryptobox.h"
#ifdef HAVE_SCHED_YIELD
#include <sched.h>
@@ -41,6 +43,42 @@
*/
#undef MEMORY_GREEDY
+
+#define ENTRY_LEN 128
+#define ENTRY_NELTS 64
+
+struct entry_elt {
+ gsize fragmentation;
+ gsize 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)
+{
+ return rspamd_cryptobox_fast_hash (str, strlen (str), rspamd_hash_seed ());
+}
+
+static inline int
+rspamd_entry_equal (const char *k1, const char *k2)
+{
+ return strcmp (k1, k2) == 0;
+}
+
+
+KHASH_INIT(mempool_entry, const gchar *, struct rspamd_mempool_entry_point,
+ 1, rspamd_entry_hash, rspamd_entry_equal)
+
+static khash_t(mempool_entry) *mempool_entries = NULL;
+
+
/* Internal statistic */
static rspamd_mempool_stat_t *mem_pool_stat = NULL;
/* Environment variable */
@@ -60,6 +98,56 @@ pool_chain_free (struct _pool_chain *chain)
chain->len - occupied : 0);
}
+/* By default allocate 8Kb chunks of memory */
+#define FIXED_POOL_SIZE 4096
+
+static inline struct rspamd_mempool_entry_point *
+rspamd_mempool_entry_new (const gchar *loc)
+{
+ struct rspamd_mempool_entry_point *entry;
+ gint r;
+ khiter_t k;
+
+ k = kh_put (mempool_entry, mempool_entries, loc, &r);
+
+ if (r >= 0) {
+ entry = &kh_value (mempool_entries, k);
+ memset (entry, 0, sizeof (*entry));
+#ifdef HAVE_GETPAGESIZE
+ entry->cur_suggestion = MAX (getpagesize (), FIXED_POOL_SIZE);
+#else
+ entry->cur_suggestion = MAX (sysconf (_SC_PAGESIZE), FIXED_POOL_SIZE);
+#endif
+ }
+ else {
+ g_assert_not_reached ();
+ }
+
+ return entry;
+}
+
+static inline struct rspamd_mempool_entry_point *
+rspamd_mempool_get_entry (const gchar *loc)
+{
+ khiter_t k;
+ struct rspamd_mempool_entry_point *elt;
+
+ if (mempool_entries == NULL) {
+ mempool_entries = kh_init (mempool_entry);
+ }
+ else {
+ k = kh_get (mempool_entry, mempool_entries, loc);
+
+ if (k != kh_end (mempool_entries)) {
+ elt = &kh_value (mempool_entries, k);
+
+ return elt;
+ }
+ }
+
+ return rspamd_mempool_entry_new (loc);
+}
+
static struct _pool_chain *
rspamd_mempool_chain_new (gsize size, enum rspamd_mempool_chain_type pool_type)
{
@@ -192,7 +280,7 @@ rspamd_mempool_append_chain (rspamd_mempool_t * pool,
* @return new memory pool object
*/
rspamd_mempool_t *
-rspamd_mempool_new (gsize size, const gchar *tag)
+rspamd_mempool_new_ (gsize size, const gchar *tag, const gchar *loc)
{
rspamd_mempool_t *new;
gpointer map;
@@ -614,10 +702,8 @@ rspamd_mempool_stat_reset (void)
}
}
-/* By default allocate 8Kb chunks of memory */
-#define FIXED_POOL_SIZE 8192
gsize
-rspamd_mempool_suggest_size (void)
+rspamd_mempool_suggest_size_ (const char *loc)
{
#ifdef HAVE_GETPAGESIZE
return MAX (getpagesize (), FIXED_POOL_SIZE);
diff --git a/src/libutil/mem_pool.h b/src/libutil/mem_pool.h
index b3ea87099..59a4d0615 100644
--- a/src/libutil/mem_pool.h
+++ b/src/libutil/mem_pool.h
@@ -89,6 +89,7 @@ struct rspamd_mempool_tag {
/**
* Memory pool type
*/
+struct rspamd_mempool_entry_point;
struct rspamd_mutex_s;
typedef struct memory_pool_s {
GPtrArray *pools[RSPAMD_MEMPOOL_MAX];
@@ -96,6 +97,7 @@ typedef struct memory_pool_s {
GPtrArray *trash_stack;
GHashTable *variables; /**< private memory pool variables */
gsize elt_len; /**< size of an element */
+ struct rspamd_mempool_entry_point *entry;
struct rspamd_mempool_tag tag; /**< memory pool tag */
} rspamd_mempool_t;
@@ -120,7 +122,8 @@ typedef struct memory_pool_stat_s {
* @param size size of pool's page
* @return new memory pool object
*/
-rspamd_mempool_t *rspamd_mempool_new (gsize size, const gchar *tag);
+rspamd_mempool_t * rspamd_mempool_new_ (gsize size, const gchar *tag, const gchar *loc);
+#define rspamd_mempool_new(size, tag) rspamd_mempool_new_((size), (tag), G_STRLOC)
/**
* Get memory from pool
@@ -293,7 +296,8 @@ void rspamd_mempool_stat_reset (void);
* Get optimal pool size based on page size for this system
* @return size of memory page in system
*/
-gsize rspamd_mempool_suggest_size (void);
+#define rspamd_mempool_suggest_size() rspamd_mempool_suggest_size_(G_STRLOC)
+gsize rspamd_mempool_suggest_size_ (const char *loc);
/**
* Set memory pool variable