1 /*
2 Copyright (c) 2004-2012 NFG Net Facilities Group BV support@nfg.nl
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later
8 version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "dbmail.h"
21 #include "dm_mempool.h"
22 #include "mpool/mpool.h"
23
24 #define THIS_MODULE "mempool"
25
26 #define M Mempool_T
27
28 #define fail_unless(a) assert(a)
29
30 struct M {
31 pthread_mutex_t lock;
32 mpool_t *pool;
33 };
34
mempool_open(void)35 M mempool_open(void)
36 {
37 M MP;
38 mpool_t *pool = NULL;
39 static gboolean env_mpool = false;
40 static gboolean use_mpool = false;
41
42 if (! env_mpool) {
43 char *dm_pool = getenv("DM_POOL");
44 if (MATCH(dm_pool, "yes"))
45 use_mpool = true;
46 env_mpool = true;
47 }
48 if (use_mpool)
49 pool = mpool_open(0,0,0,NULL);
50 else
51 pool = NULL;
52
53 MP = mpool_alloc(pool, sizeof(*MP), NULL);
54
55 if (pthread_mutex_init(&MP->lock, NULL)) {
56 perror("pthread_mutex_init failed");
57 mpool_free(pool, MP, sizeof(*MP));
58 if (pool)
59 mpool_close(pool);
60 return NULL;
61 }
62
63 MP->pool = pool;
64 return MP;
65 }
66
mempool_pop(M MP,size_t blocksize)67 void * mempool_pop(M MP, size_t blocksize)
68 {
69 int error;
70 PLOCK(MP->lock);
71 void *block = mpool_calloc(MP->pool, 1, blocksize, &error);
72 PUNLOCK(MP->lock);
73 if (error != MPOOL_ERROR_NONE)
74 TRACE(TRACE_ERR, "%s", mpool_strerror(error));
75 return block;
76 }
77
mempool_resize(M MP,void * block,size_t oldsize,size_t newsize)78 void * mempool_resize(M MP, void *block, size_t oldsize, size_t newsize)
79 {
80 int error;
81 PLOCK(MP->lock);
82 void *newblock = mpool_resize(MP->pool, block, oldsize, newsize, &error);
83 PUNLOCK(MP->lock);
84 if (error != MPOOL_ERROR_NONE)
85 TRACE(TRACE_ERR, "%s", mpool_strerror(error));
86 assert (error == MPOOL_ERROR_NONE);
87 return newblock;
88 }
89
mempool_push(M MP,void * block,size_t blocksize)90 void mempool_push(M MP, void *block, size_t blocksize)
91 {
92 int error;
93 PLOCK(MP->lock);
94 if ((error = mpool_free(MP->pool, block, blocksize)) != MPOOL_ERROR_NONE)
95 TRACE(TRACE_ERR, "%s", mpool_strerror(error));
96
97 fail_unless(error == MPOOL_ERROR_NONE);
98 PUNLOCK(MP->lock);
99 }
100
mempool_stats(M MP)101 void mempool_stats(M MP)
102 {
103 unsigned int page_size;
104 unsigned long num_alloced, user_alloced, max_alloced, tot_alloced;
105 mpool_stats(MP->pool, &page_size, &num_alloced, &user_alloced,
106 &max_alloced, &tot_alloced);
107 TRACE(TRACE_DEBUG, "[%p] page_size: %u num: %" PRIu64 " user: %" PRIu64 " "
108 "max: %" PRIu64 " tot: %" PRIu64 "", MP->pool,
109 page_size, (uint64_t)num_alloced, (uint64_t)user_alloced,
110 (uint64_t)max_alloced, (uint64_t)tot_alloced);
111 }
112
mempool_close(M * MP)113 void mempool_close(M *MP)
114 {
115 int error;
116 M mp = *MP;
117 pthread_mutex_t lock = mp->lock;
118 PLOCK(lock);
119 mpool_t *pool = mp->pool;
120 if (pool) {
121 mempool_stats(mp);
122 if ((error = mpool_close(pool)) != MPOOL_ERROR_NONE)
123 TRACE(TRACE_ERR, "%s", mpool_strerror(error));
124 } else {
125 free(mp);
126 }
127 PUNLOCK(lock);
128 pthread_mutex_destroy(&lock);
129 mp = NULL;
130 }
131
132 #undef M
133