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