glusterfs  8.2
About: GlusterFS is a network/cluster filesystem. The storage server (or each in a cluster) runs glusterfsd and the clients use mount command or glusterfs client to mount the exported filesystem. Release series 8.x (latest version).
  Fossies Dox: glusterfs-8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

mem-pool.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3  This file is part of GlusterFS.
4 
5  This file is licensed to you under your choice of the GNU Lesser
6  General Public License, version 3 or any later version (LGPLv3 or
7  later), or the GNU General Public License, version 2 (GPLv2), in all
8  cases as published by the Free Software Foundation.
9 */
10 
11 #ifndef _MEM_POOL_H_
12 #define _MEM_POOL_H_
13 
14 #include "glusterfs/list.h"
15 #include "glusterfs/atomic.h"
16 #include "glusterfs/logging.h"
17 #include "glusterfs/mem-types.h"
18 #include "glusterfs/glusterfs.h" /* for glusterfs_ctx_t */
19 #include <stdlib.h>
20 #include <inttypes.h>
21 #include <string.h>
22 #include <stdarg.h>
23 
24 /*
25  * Need this for unit tests since inline functions
26  * access memory allocation and need to use the
27  * unit test versions
28  */
29 #ifdef UNIT_TESTING
30 #include <stddef.h>
31 #include <setjmp.h>
32 #include <cmocka.h>
33 #endif
34 
35 #define GF_MEM_TRAILER_SIZE 8
36 #define GF_MEM_HEADER_MAGIC 0xCAFEBABE
37 #define GF_MEM_TRAILER_MAGIC 0xBAADF00D
38 #define GF_MEM_INVALID_MAGIC 0xDEADC0DE
39 
40 #define POOL_SMALLEST 7 /* i.e. 128 */
41 #define POOL_LARGEST 20 /* i.e. 1048576 */
42 #define NPOOLS (POOL_LARGEST - POOL_SMALLEST + 1)
43 
44 struct mem_acct_rec {
45  const char *typestr;
46  uint64_t size;
47  uint64_t max_size;
48  uint64_t total_allocs;
49  uint32_t num_allocs;
50  uint32_t max_num_allocs;
52 #ifdef DEBUG
53  struct list_head obj_list;
54 #endif
55 };
56 
57 struct mem_acct {
58  uint32_t num_types;
60  struct mem_acct_rec rec[0];
61 };
62 
63 struct mem_header {
64  uint32_t type;
65  size_t size;
66  struct mem_acct *mem_acct;
67  uint32_t magic;
68 #ifdef DEBUG
69  struct list_head acct_list;
70 #endif
71  int padding[8];
72 };
73 
74 #define GF_MEM_HEADER_SIZE (sizeof(struct mem_header))
75 
76 #ifdef DEBUG
77 struct mem_invalid {
78  uint32_t magic;
79  void *mem_acct;
80  uint32_t type;
81  size_t size;
82  void *baseaddr;
83 };
84 #endif
85 
86 void *
87 __gf_calloc(size_t cnt, size_t size, uint32_t type, const char *typestr);
88 
89 void *
90 __gf_malloc(size_t size, uint32_t type, const char *typestr);
91 
92 void *
93 __gf_realloc(void *ptr, size_t size);
94 
95 int
96 gf_vasprintf(char **string_ptr, const char *format, va_list arg);
97 
98 int
99 gf_asprintf(char **string_ptr, const char *format, ...)
100  __attribute__((__format__(__printf__, 2, 3)));
101 
102 void
103 __gf_free(void *ptr);
104 
105 static inline void *
107 {
108  void *ptr = NULL;
109 
110  ptr = malloc(size);
111  if (!ptr)
112  gf_msg_nomem("", GF_LOG_ALERT, size);
113 
114  return ptr;
115 }
116 
117 static inline void *
118 __gf_default_calloc(int cnt, size_t size)
119 {
120  void *ptr = NULL;
121 
122  ptr = calloc(cnt, size);
123  if (!ptr)
124  gf_msg_nomem("", GF_LOG_ALERT, (cnt * size));
125 
126  return ptr;
127 }
128 
129 static inline void *
130 __gf_default_realloc(void *oldptr, size_t size)
131 {
132  void *ptr = NULL;
133 
134  ptr = realloc(oldptr, size);
135  if (!ptr)
136  gf_msg_nomem("", GF_LOG_ALERT, size);
137 
138  return ptr;
139 }
140 
141 #define MALLOC(size) __gf_default_malloc(size)
142 #define CALLOC(cnt, size) __gf_default_calloc(cnt, size)
143 #define REALLOC(ptr, size) __gf_default_realloc(ptr, size)
144 
145 #define FREE(ptr) \
146  do { \
147  if (ptr != NULL) { \
148  free((void *)ptr); \
149  ptr = (void *)0xeeeeeeee; \
150  } \
151  } while (0)
152 
153 #define GF_CALLOC(nmemb, size, type) __gf_calloc(nmemb, size, type, #type)
154 
155 #define GF_MALLOC(size, type) __gf_malloc(size, type, #type)
156 
157 #define GF_REALLOC(ptr, size) __gf_realloc(ptr, size)
158 
159 #define GF_FREE(free_ptr) __gf_free(free_ptr)
160 
161 static inline char *
162 gf_strndup(const char *src, size_t len)
163 {
164  char *dup_str = NULL;
165 
166  if (!src) {
167  goto out;
168  }
169 
170  dup_str = GF_MALLOC(len + 1, gf_common_mt_strdup);
171  if (!dup_str) {
172  goto out;
173  }
174 
175  memcpy(dup_str, src, len);
176  dup_str[len] = '\0';
177 out:
178  return dup_str;
179 }
180 
181 static inline char *
182 gf_strdup(const char *src)
183 {
184  if (!src)
185  return NULL;
186 
187  return gf_strndup(src, strlen(src));
188 }
189 
190 static inline void *
191 gf_memdup(const void *src, size_t size)
192 {
193  void *dup_mem = NULL;
194 
195  dup_mem = GF_MALLOC(size, gf_common_mt_memdup);
196  if (!dup_mem)
197  goto out;
198 
199  memcpy(dup_mem, src, size);
200 
201 out:
202  return dup_mem;
203 }
204 
205 /* kind of 'header' for the actual mem_pool_shared structure, this might make
206  * it possible to dump some more details in a statedump */
207 struct mem_pool {
208  /* object size, without pooled_obj_hdr_t */
209  unsigned long sizeof_type;
210  unsigned long count; /* requested pool size (unused) */
211  char *name;
212  gf_atomic_t active; /* current allocations */
213 #ifdef DEBUG
214  gf_atomic_t hit; /* number of allocations served from pt_pool */
215  gf_atomic_t miss; /* number of std allocs due to miss */
216 #endif
217  struct list_head owner; /* glusterfs_ctx_t->mempool_list */
218  glusterfs_ctx_t *ctx; /* take ctx->lock when updating owner */
219 
220  struct mem_pool_shared *pool; /* the initial pool that was returned */
221 };
222 
223 typedef struct pooled_obj_hdr {
224  unsigned long magic;
227  unsigned int power_of_two;
228 
229  /* track the pool that was used to request this object */
230  struct mem_pool *pool;
232 
233 /* Each memory block inside a pool has a fixed size that is a power of two.
234  * However each object will have a header that will reduce the available
235  * space. */
236 #define AVAILABLE_SIZE(p2) ((1UL << (p2)) - sizeof(pooled_obj_hdr_t))
237 
238 typedef struct per_thread_pool {
239  /* the pool that was used to request this allocation */
241  /* Everything else is protected by our own lock. */
245 
246 typedef struct per_thread_pool_list {
247  /* thr_list is used to place the TLS pool_list into the active global list
248  * (pool_threads) or the inactive global list (pool_free_threads). It's
249  * protected by the global pool_lock. */
250  struct list_head thr_list;
251 
252  /* This lock is used to update poison and the hot/cold lists of members
253  * of 'pools' array. */
254  pthread_spinlock_t lock;
255 
256  /* This field is used to mark a pool_list as not being owned by any thread.
257  * This means that the sweeper thread won't be cleaning objects stored in
258  * its pools. mem_put() uses it to decide if the object being released is
259  * placed into its original pool_list or directly destroyed. */
260  bool poison;
261 
262  /*
263  * There's really more than one pool, but the actual number is hidden
264  * in the implementation code so we just make it a single-element array
265  * here.
266  */
269 
270 /* actual pool structure, shared between different mem_pools */
272  unsigned int power_of_two;
273  /*
274  * Updates to these are *not* protected by a global lock, so races
275  * could occur and the numbers might be slightly off. Don't expect
276  * them to line up exactly. It's the general trends that matter, and
277  * it's not worth the locked-bus-cycle overhead to make these precise.
278  */
283 };
284 
285 void
286 mem_pools_init(void); /* start the pool_sweeper thread */
287 void
288 mem_pools_fini(void); /* cleanup memory pools */
289 
290 struct mem_pool *
292  unsigned long count, char *name);
293 
294 #define mem_pool_new(type, count) \
295  mem_pool_new_fn(THIS->ctx, sizeof(type), count, #type)
296 
297 #define mem_pool_new_ctx(ctx, type, count) \
298  mem_pool_new_fn(ctx, sizeof(type), count, #type)
299 
300 void
301 mem_put(void *ptr);
302 void *
303 mem_get(struct mem_pool *pool);
304 void *
305 mem_get0(struct mem_pool *pool);
306 
307 void
309 
310 void
312 
313 void
315 
316 #endif /* _MEM_POOL_H */
per_thread_pool_list::poison
bool poison
Definition: mem-pool.h:260
out
#define out(x...)
Definition: gcrawler.c:35
_glusterfs_ctx
Definition: glusterfs.h:618
__gf_default_realloc
static void * __gf_default_realloc(void *oldptr, size_t size)
Definition: mem-pool.h:130
mem_get0
void * mem_get0(struct mem_pool *pool)
Definition: mem-pool.c:703
glusterfs.h
mem_pool
Definition: mem-pool.h:207
pooled_obj_hdr::magic
unsigned long magic
Definition: mem-pool.h:224
mem_acct_rec::size
uint64_t size
Definition: mem-pool.h:46
__gf_realloc
void * __gf_realloc(void *ptr, size_t size)
Definition: mem-pool.c:185
mem_pool_new_fn
struct mem_pool * mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, unsigned long count, char *name)
Definition: mem-pool.c:637
mem_pool::count
unsigned long count
Definition: mem-pool.h:210
mem_pool_shared::allocs_cold
gf_atomic_int64_t allocs_cold
Definition: mem-pool.h:280
GF_LOG_ALERT
@ GF_LOG_ALERT
Definition: logging.h:71
gf_lock_t
pthread_mutex_t gf_lock_t
Definition: locking.h:74
mem_acct_rec::lock
gf_lock_t lock
Definition: mem-pool.h:51
per_thread_pool_list
Definition: mem-pool.h:246
gf_memdup
static void * gf_memdup(const void *src, size_t size)
Definition: mem-pool.h:191
per_thread_pool_list::thr_list
struct list_head thr_list
Definition: mem-pool.h:250
gf_common_mt_strdup
@ gf_common_mt_strdup
Definition: mem-types.h:40
gf_common_mt_memdup
@ gf_common_mt_memdup
Definition: mem-types.h:38
pooled_obj_hdr::pool_list
struct per_thread_pool_list * pool_list
Definition: mem-pool.h:226
gf_asprintf
int gf_asprintf(char **string_ptr, const char *format,...)
Definition: mem-pool.c:237
mem_pool::name
char * name
Definition: mem-pool.h:211
pooled_obj_hdr::next
struct pooled_obj_hdr * next
Definition: mem-pool.h:225
mem_acct::num_types
uint32_t num_types
Definition: mem-pool.h:58
mem_pool_shared::allocs_stdc
gf_atomic_int64_t allocs_stdc
Definition: mem-pool.h:281
mem_header
Definition: mem-pool.h:63
__gf_default_malloc
static void * __gf_default_malloc(size_t size)
Definition: mem-pool.h:106
per_thread_pool_list_t
struct per_thread_pool_list per_thread_pool_list_t
mem_pool_shared::frees_to_list
gf_atomic_int64_t frees_to_list
Definition: mem-pool.h:282
pooled_obj_hdr::power_of_two
unsigned int power_of_two
Definition: mem-pool.h:227
per_thread_pool::cold_list
pooled_obj_hdr_t * cold_list
Definition: mem-pool.h:243
mem_acct_rec
Definition: mem-pool.h:44
list_head
Definition: list.h:14
per_thread_pool::parent
struct mem_pool_shared * parent
Definition: mem-pool.h:240
mem_header::magic
uint32_t magic
Definition: mem-pool.h:67
mem_acct_rec::typestr
const char * typestr
Definition: mem-pool.h:45
mem_pool_thread_destructor
void mem_pool_thread_destructor(per_thread_pool_list_t *pool_list)
Definition: mem-pool.c:480
mem_acct_rec::max_size
uint64_t max_size
Definition: mem-pool.h:47
mem_pool_destroy
void mem_pool_destroy(struct mem_pool *pool)
Definition: mem-pool.c:901
__gf_calloc
void * __gf_calloc(size_t cnt, size_t size, uint32_t type, const char *typestr)
Definition: mem-pool.c:136
pooled_obj_hdr_t
struct pooled_obj_hdr pooled_obj_hdr_t
mem_acct
Definition: mem-pool.h:57
__gf_free
void __gf_free(void *ptr)
Definition: mem-pool.c:306
mem_put
void mem_put(void *ptr)
Definition: mem-pool.c:849
pooled_obj_hdr::pool
struct mem_pool * pool
Definition: mem-pool.h:230
mem_pool::sizeof_type
unsigned long sizeof_type
Definition: mem-pool.h:209
mem_acct::refcnt
gf_atomic_int64_t refcnt
Definition: mem-pool.h:59
mem_acct_rec::max_num_allocs
uint32_t max_num_allocs
Definition: mem-pool.h:50
mem_header::size
size_t size
Definition: mem-pool.h:65
name
char * name
Definition: xdr-nfs3.h:948
mem_acct_rec::num_allocs
uint32_t num_allocs
Definition: mem-pool.h:49
gf_mem_acct_enable_set
void gf_mem_acct_enable_set(void *ctx)
Definition: mem-pool.c:21
mem_acct_rec::total_allocs
uint64_t total_allocs
Definition: mem-pool.h:48
mem_pools_init
void mem_pools_init(void)
Definition: mem-pool.c:570
per_thread_pool_list::pools
per_thread_pool_t pools[1]
Definition: mem-pool.h:267
pooled_obj_hdr
Definition: mem-pool.h:223
mem_header::mem_acct
struct mem_acct * mem_acct
Definition: mem-pool.h:66
mem_pool_shared::allocs_hot
gf_atomic_int64_t allocs_hot
Definition: mem-pool.h:279
mem_pool_shared::power_of_two
unsigned int power_of_two
Definition: mem-pool.h:272
mem_header::type
uint32_t type
Definition: mem-pool.h:64
logging.h
mem_pools_fini
void mem_pools_fini(void)
Definition: mem-pool.c:583
mem_pool::pool
struct mem_pool_shared * pool
Definition: mem-pool.h:220
__gf_default_calloc
static void * __gf_default_calloc(int cnt, size_t size)
Definition: mem-pool.h:118
gf_vasprintf
int gf_vasprintf(char **string_ptr, const char *format, va_list arg)
Definition: mem-pool.c:209
atomic.h
mem_header::padding
int padding[8]
Definition: mem-pool.h:71
mem_pool::active
gf_atomic_int64_t active
Definition: mem-pool.h:212
mem_acct::rec
struct mem_acct_rec rec[0]
Definition: mem-pool.h:60
per_thread_pool
Definition: mem-pool.h:238
src
Definition: __init__.py:1
mem_get
void * mem_get(struct mem_pool *pool)
Definition: mem-pool.c:826
list.h
per_thread_pool_t
struct per_thread_pool per_thread_pool_t
gf_atomic_t
#define gf_atomic_t
Definition: atomic.h:111
per_thread_pool::hot_list
pooled_obj_hdr_t * hot_list
Definition: mem-pool.h:242
__gf_malloc
void * __gf_malloc(size_t size, uint32_t type, const char *typestr)
Definition: mem-pool.c:162
gf_msg_nomem
#define gf_msg_nomem(dom, level, size)
Definition: logging.h:263
gf_strdup
static char * gf_strdup(const char *src)
Definition: mem-pool.h:182
S40ufo-stop.type
type
Definition: S40ufo-stop.py:15
mem-types.h
GF_MALLOC
#define GF_MALLOC(size, type)
Definition: mem-pool.h:155
mem_pool::owner
struct list_head owner
Definition: mem-pool.h:217
mem_pool::ctx
glusterfs_ctx_t * ctx
Definition: mem-pool.h:218
gf_strndup
static char * gf_strndup(const char *src, size_t len)
Definition: mem-pool.h:162
per_thread_pool_list::lock
pthread_spinlock_t lock
Definition: mem-pool.h:254
mem_pool_shared
Definition: mem-pool.h:271