1 /**
2 * Copyright (C) 2008 Happy Fish / YuQing
3 *
4 * FastDFS may be copied only under the terms of the GNU General
5 * Public License V3, which may be found in the FastDFS source kit.
6 * Please visit the FastDFS Home Page http://www.fastken.com/ for more detail.
7 **/
8
9 //fast_mblock.h
10
11 #ifndef _FAST_MBLOCK_H
12 #define _FAST_MBLOCK_H
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <pthread.h>
18 #include "common_define.h"
19 #include "chain.h"
20
21 #define FAST_MBLOCK_NAME_SIZE 32
22
23 #define FAST_MBLOCK_ORDER_BY_ALLOC_BYTES 1
24 #define FAST_MBLOCK_ORDER_BY_ELEMENT_SIZE 2
25
26 /* free node chain */
27 struct fast_mblock_node
28 {
29 struct fast_mblock_node *next;
30 int offset; //trunk offset
31 int recycle_timestamp;
32 char data[0]; //the data buffer
33 };
34
35 /* malloc chain */
36 struct fast_mblock_malloc
37 {
38 int64_t ref_count; //refference count
39 struct fast_mblock_malloc *prev;
40 struct fast_mblock_malloc *next;
41 };
42
43 struct fast_mblock_chain {
44 struct fast_mblock_node *head;
45 struct fast_mblock_node *tail;
46 };
47
48 typedef int (*fast_mblock_alloc_init_func)(void *element);
49
50 typedef int (*fast_mblock_malloc_trunk_check_func)(
51 const int alloc_bytes, void *args);
52
53 typedef void (*fast_mblock_malloc_trunk_notify_func)(
54 const int alloc_bytes, void *args);
55
56 struct fast_mblock_info
57 {
58 char name[FAST_MBLOCK_NAME_SIZE];
59 int element_size; //element size
60 int element_total_count; //total element count
61 int element_used_count; //used element count
62 int trunk_size; //trunk size
63 int trunk_total_count; //total trunk count
64 int trunk_used_count; //used trunk count
65 int instance_count; //instance count
66 };
67
68 struct fast_mblock_trunks
69 {
70 struct fast_mblock_malloc head; //malloc chain to be freed
71 };
72
73 struct fast_mblock_malloc_trunk_callback
74 {
75 fast_mblock_malloc_trunk_check_func check_func;
76 fast_mblock_malloc_trunk_notify_func notify_func;
77 void *args;
78 };
79
80 struct fast_mblock_man
81 {
82 struct fast_mblock_info info;
83 int alloc_elements_once; //alloc elements once
84 struct fast_mblock_node *free_chain_head; //free node chain
85 struct fast_mblock_trunks trunks;
86 struct fast_mblock_chain delay_free_chain; //delay free node chain
87
88 fast_mblock_alloc_init_func alloc_init_func;
89 struct fast_mblock_malloc_trunk_callback malloc_trunk_callback;
90
91 bool need_lock; //if need mutex lock
92 pthread_mutex_t lock; //the lock for read / write free node chain
93 struct fast_mblock_man *prev; //for stat manager
94 struct fast_mblock_man *next; //for stat manager
95 };
96
97 #define GET_BLOCK_SIZE(info) \
98 (MEM_ALIGN(sizeof(struct fast_mblock_node) + (info).element_size))
99
100 #define fast_mblock_get_block_size(mblock) GET_BLOCK_SIZE(mblock->info)
101
102 #define fast_mblock_to_node_ptr(data_ptr) \
103 (struct fast_mblock_node *)((char *)data_ptr - ((size_t)(char *) \
104 &((struct fast_mblock_node *)0)->data))
105
106 #ifdef __cplusplus
107 extern "C" {
108 #endif
109
110 #define fast_mblock_init(mblock, element_size, alloc_elements_once) \
111 fast_mblock_init_ex(mblock, element_size, alloc_elements_once, NULL, true)
112
113 /**
114 mblock init
115 parameters:
116 mblock: the mblock pointer
117 element_size: element size, such as sizeof(struct xxx)
118 alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
119 init_func: the init function
120 need_lock: if need lock
121 return error no, 0 for success, != 0 fail
122 */
123 int fast_mblock_init_ex(struct fast_mblock_man *mblock,
124 const int element_size, const int alloc_elements_once,
125 fast_mblock_alloc_init_func init_func, const bool need_lock);
126
127 /**
128 mblock init
129 parameters:
130 name: the mblock name
131 mblock: the mblock pointer
132 element_size: element size, such as sizeof(struct xxx)
133 alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
134 init_func: the init function
135 need_lock: if need lock
136 malloc_trunk_check: the malloc trunk check function pointor
137 malloc_trunk_notify: the malloc trunk notify function pointor
138 malloc_trunk_args: the malloc trunk args
139 return error no, 0 for success, != 0 fail
140 */
141 int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
142 const int element_size, const int alloc_elements_once,
143 fast_mblock_alloc_init_func init_func, const bool need_lock,
144 fast_mblock_malloc_trunk_check_func malloc_trunk_check,
145 fast_mblock_malloc_trunk_notify_func malloc_trunk_notify,
146 void *malloc_trunk_args);
147
148 /**
149 mblock init
150 parameters:
151 name: the mblock name
152 mblock: the mblock pointer
153 element_size: element size, such as sizeof(struct xxx)
154 alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
155 init_func: the init function
156 need_lock: if need lock
157 return error no, 0 for success, != 0 fail
158 */
fast_mblock_init_ex1(struct fast_mblock_man * mblock,const char * name,const int element_size,const int alloc_elements_once,fast_mblock_alloc_init_func init_func,const bool need_lock)159 static inline int fast_mblock_init_ex1(struct fast_mblock_man *mblock,
160 const char *name, const int element_size, const int alloc_elements_once,
161 fast_mblock_alloc_init_func init_func, const bool need_lock)
162 {
163 return fast_mblock_init_ex2(mblock, name, element_size,
164 alloc_elements_once, init_func, need_lock, NULL, NULL, NULL);
165 }
166
167 /**
168 mblock destroy
169 parameters:
170 mblock: the mblock pointer
171 */
172 void fast_mblock_destroy(struct fast_mblock_man *mblock);
173
174 /**
175 alloc a node from the mblock
176 parameters:
177 mblock: the mblock pointer
178 return the alloced node, return NULL if fail
179 */
180 struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock);
181
182 /**
183 free a node (put a node to the mblock)
184 parameters:
185 mblock: the mblock pointer
186 pNode: the node to free
187 return 0 for success, return none zero if fail
188 */
189 int fast_mblock_free(struct fast_mblock_man *mblock,
190 struct fast_mblock_node *pNode);
191
192 /**
193 delay free a node (put a node to the mblock)
194 parameters:
195 mblock: the mblock pointer
196 pNode: the node to free
197 delay: delay seconds to free
198 return 0 for success, return none zero if fail
199 */
200 int fast_mblock_delay_free(struct fast_mblock_man *mblock,
201 struct fast_mblock_node *pNode, const int delay);
202
203 /**
204 alloc a object from the mblock
205 parameters:
206 mblock: the mblock pointer
207 return the alloced object, return NULL if fail
208 */
fast_mblock_alloc_object(struct fast_mblock_man * mblock)209 static inline void *fast_mblock_alloc_object(struct fast_mblock_man *mblock)
210 {
211 struct fast_mblock_node *node;
212 node = fast_mblock_alloc(mblock);
213 if (node == NULL)
214 {
215 return NULL;
216 }
217 return node->data;
218 }
219
220 /**
221 free a object (put the object to the mblock)
222 parameters:
223 mblock: the mblock pointer
224 object: the object to free
225 return 0 for success, return none zero if fail
226 */
fast_mblock_free_object(struct fast_mblock_man * mblock,void * object)227 static inline int fast_mblock_free_object(struct fast_mblock_man *mblock,
228 void *object)
229 {
230 return fast_mblock_free(mblock, fast_mblock_to_node_ptr(object));
231 }
232
233 /**
234 delay free a object (put a node to the mblock)
235 parameters:
236 mblock: the mblock pointer
237 pNode: the node to free
238 delay: delay seconds to free
239 return 0 for success, return none zero if fail
240 */
fast_mblock_delay_free_object(struct fast_mblock_man * mblock,void * object,const int delay)241 static inline int fast_mblock_delay_free_object(struct fast_mblock_man *mblock,
242 void *object, const int delay)
243 {
244 return fast_mblock_delay_free(mblock, fast_mblock_to_node_ptr(object), delay);
245 }
246
247 /**
248 get node count of the mblock
249 parameters:
250 mblock: the mblock pointer
251 return the free node count of the mblock, return -1 if fail
252 */
253 int fast_mblock_free_count(struct fast_mblock_man *mblock);
254
255 /**
256 get delay free node count of the mblock
257 parameters:
258 mblock: the mblock pointer
259 return the delay free node count of the mblock, return -1 if fail
260 */
261 int fast_mblock_delay_free_count(struct fast_mblock_man *mblock);
262
263 #define fast_mblock_total_count(mblock) (mblock)->total_count
264
265 /**
266 init mblock manager
267 parameters:
268 return error no, 0 for success, != 0 fail
269 */
270 int fast_mblock_manager_init();
271
272 /**
273 get mblock stat
274 parameters:
275 stats: return mblock stats
276 size: max size of stats
277 count: return mblock stat count
278 return error no, 0 for success, != 0 fail
279 */
280 int fast_mblock_manager_stat(struct fast_mblock_info *stats,
281 const int size, int *count);
282
283
284 /**
285 print mblock manager stat
286 parameters:
287 hide_empty: if hide empty
288 order_by: order by which field
289 return error no, 0 for success, != 0 fail
290 */
291 int fast_mblock_manager_stat_print_ex(const bool hide_empty, const int order_by);
292
293 #define fast_mblock_manager_stat_print(hide_empty) \
294 fast_mblock_manager_stat_print_ex(hide_empty, FAST_MBLOCK_ORDER_BY_ALLOC_BYTES)
295
296 typedef void (*fast_mblock_free_trunks_func)(struct fast_mblock_man *mblock,
297 struct fast_mblock_malloc *freelist);
298
299 /**
300 free the trunks
301 parameters:
302 mblock: the mblock pointer
303 freelist: the trunks to free
304 return error no, 0 for success, != 0 fail
305 */
306 void fast_mblock_free_trunks(struct fast_mblock_man *mblock,
307 struct fast_mblock_malloc *freelist);
308
309 /**
310 reclaim the free trunks of the mblock
311 parameters:
312 mblock: the mblock pointer
313 reclaim_target: reclaim target trunks, 0 for no limit
314 reclaim_count: reclaimed trunk count
315 freelist: the free trunks
316 return error no, 0 for success, != 0 fail
317 */
318 int fast_mblock_reclaim(struct fast_mblock_man *mblock,
319 const int reclaim_target, int *reclaim_count,
320 fast_mblock_free_trunks_func free_trunks_func);
321
322 #ifdef __cplusplus
323 }
324 #endif
325
326 #endif
327
328