fast_mblock.h 10.3 KB
Newer Older
Y
YuQing 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * Copyright (c) 2020 YuQing <384681@qq.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the Lesser GNU General Public License, version 3
 * or later ("LGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the Lesser GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
Y
yuqing 已提交
15 16 17 18 19 20 21 22 23 24 25

//fast_mblock.h

#ifndef _FAST_MBLOCK_H
#define _FAST_MBLOCK_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "common_define.h"
Y
YuQing 已提交
26
#include "fc_memory.h"
Y
yuqing 已提交
27 28
#include "chain.h"

Y
yuqing 已提交
29
#define FAST_MBLOCK_NAME_SIZE 32
Y
yuqing 已提交
30

Y
yuqing 已提交
31 32 33
#define FAST_MBLOCK_ORDER_BY_ALLOC_BYTES    1
#define FAST_MBLOCK_ORDER_BY_ELEMENT_SIZE   2

Y
yuqing 已提交
34 35 36
/* free node chain */ 
struct fast_mblock_node
{
37
    struct fast_mblock_node *next;
Y
yuqing 已提交
38
    int offset;    //trunk offset
Y
yuqing 已提交
39
    int recycle_timestamp;
40
    char data[0];   //the data buffer
Y
yuqing 已提交
41 42 43 44 45
};

/* malloc chain */
struct fast_mblock_malloc
{
46 47 48
    int64_t ref_count; //refference count
    int alloc_count;   //allocated element count
    int trunk_size;    //trunk bytes
49 50
    struct fast_mblock_malloc *prev;
    struct fast_mblock_malloc *next;
Y
yuqing 已提交
51 52
};

Y
yuqing 已提交
53 54 55 56 57
struct fast_mblock_chain {
	struct fast_mblock_node *head;
	struct fast_mblock_node *tail;
};

58
typedef int (*fast_mblock_alloc_init_func)(void *element, void *args);
Y
yuqing 已提交
59

60 61 62 63 64 65
typedef int (*fast_mblock_malloc_trunk_check_func)(
	const int alloc_bytes, void *args);

typedef void (*fast_mblock_malloc_trunk_notify_func)(
	const int alloc_bytes, void *args);

Y
yuqing 已提交
66 67 68
struct fast_mblock_info
{
    char name[FAST_MBLOCK_NAME_SIZE];
69 70
    int element_size;         //element size
    int trunk_size;           //trunk size
Y
yuqing 已提交
71
    int instance_count;       //instance count
Y
YuQing 已提交
72 73 74 75 76
    int64_t element_total_count;  //total element count
    int64_t element_used_count;   //used element count
    int64_t delay_free_elements;  //delay free element count
    int64_t trunk_total_count;    //total trunk count
    int64_t trunk_used_count;     //used trunk count
Y
yuqing 已提交
77 78
};

Y
yuqing 已提交
79 80 81 82 83
struct fast_mblock_trunks
{
	struct fast_mblock_malloc head; //malloc chain to be freed
};

84 85 86 87 88 89 90
struct fast_mblock_malloc_trunk_callback
{
    fast_mblock_malloc_trunk_check_func check_func;
    fast_mblock_malloc_trunk_notify_func notify_func;
    void *args;
};

Y
yuqing 已提交
91 92
struct fast_mblock_man
{
Y
yuqing 已提交
93
    struct fast_mblock_info info;
94 95 96 97
    struct {
        int once;        //alloc elements once
        int64_t limit;   //<= 0 for no limit
    } alloc_elements;
98
    struct fast_mblock_node *free_chain_head;    //free node chain
Y
yuqing 已提交
99
    struct fast_mblock_trunks trunks;
Y
yuqing 已提交
100
    struct fast_mblock_chain delay_free_chain;   //delay free node chain
Y
yuqing 已提交
101

Y
yuqing 已提交
102
    fast_mblock_alloc_init_func alloc_init_func;
103 104
    struct fast_mblock_malloc_trunk_callback malloc_trunk_callback;

Y
YuQing 已提交
105 106 107
    bool need_lock;         //if need mutex lock
    int exceed_log_level;   //log level for exceed limit
    pthread_mutex_t lock;   //the lock for read / write free node chain
Y
yuqing 已提交
108 109
    struct fast_mblock_man *prev;  //for stat manager
    struct fast_mblock_man *next;  //for stat manager
110
    void *init_args;          //args for alloc_init_func
Y
yuqing 已提交
111 112
};

Y
yuqing 已提交
113 114 115 116 117
#define  GET_BLOCK_SIZE(info) \
	(MEM_ALIGN(sizeof(struct fast_mblock_node) + (info).element_size))

#define fast_mblock_get_block_size(mblock) GET_BLOCK_SIZE(mblock->info)

Y
yuqing 已提交
118
#define fast_mblock_to_node_ptr(data_ptr) \
Y
yuqing 已提交
119
        (struct fast_mblock_node *)((char *)data_ptr - ((size_t)(char *) \
Y
yuqing 已提交
120 121
                    &((struct fast_mblock_node *)0)->data))

Y
yuqing 已提交
122 123 124 125
#ifdef __cplusplus
extern "C" {
#endif

Y
yuqing 已提交
126
#define fast_mblock_init(mblock, element_size, alloc_elements_once) \
127
    fast_mblock_init_ex(mblock, element_size, alloc_elements_once,  \
128
            0, NULL, NULL, true)
Y
yuqing 已提交
129

Y
yuqing 已提交
130 131 132
/**
mblock init
parameters:
133 134 135
    mblock: the mblock pointer
    element_size: element size, such as sizeof(struct xxx)
    alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
136
    alloc_elements_limit: malloc elements limit, <= 0 for no limit
Y
yuqing 已提交
137
    init_func: the init function
138
    init_args: the args for init_func
Y
yuqing 已提交
139 140 141 142 143
    need_lock: if need lock
return error no, 0 for success, != 0 fail
*/
int fast_mblock_init_ex(struct fast_mblock_man *mblock,
        const int element_size, const int alloc_elements_once,
144
        const int64_t alloc_elements_limit,
145 146
        fast_mblock_alloc_init_func init_func, void *init_args,
        const bool need_lock);
Y
yuqing 已提交
147

Y
yuqing 已提交
148 149 150
/**
mblock init
parameters:
Y
yuqing 已提交
151
    name: the mblock name
152 153 154
    mblock: the mblock pointer
    element_size: element size, such as sizeof(struct xxx)
    alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
155
    alloc_elements_limit: malloc elements limit, <= 0 for no limit
Y
yuqing 已提交
156
    init_func: the init function
157
    init_args: the args for init_func
Y
yuqing 已提交
158
    need_lock: if need lock
159 160
    malloc_trunk_check: the malloc trunk check function pointor
    malloc_trunk_notify: the malloc trunk notify function pointor
Y
yuqing 已提交
161
    malloc_trunk_args: the malloc trunk args
Y
yuqing 已提交
162 163
return error no, 0 for success, != 0 fail
*/
Y
yuqing 已提交
164 165
int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
        const int element_size, const int alloc_elements_once,
166
        const int64_t alloc_elements_limit,
167 168
        fast_mblock_alloc_init_func init_func,
        void *init_args, const bool need_lock,
Y
yuqing 已提交
169 170 171 172 173 174 175 176 177 178 179
        fast_mblock_malloc_trunk_check_func malloc_trunk_check,
        fast_mblock_malloc_trunk_notify_func malloc_trunk_notify,
        void *malloc_trunk_args);

/**
mblock init
parameters:
    name: the mblock name
    mblock: the mblock pointer
    element_size: element size, such as sizeof(struct xxx)
    alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
180
    alloc_elements_limit: malloc elements limit, <= 0 for no limit
Y
yuqing 已提交
181
    init_func: the init function
182
    init_args: the args for init_func
Y
yuqing 已提交
183 184 185 186
    need_lock: if need lock
return error no, 0 for success, != 0 fail
*/
static inline int fast_mblock_init_ex1(struct fast_mblock_man *mblock,
187 188
        const char *name, const int element_size,
        const int alloc_elements_once,
189
        const int64_t alloc_elements_limit,
190 191
        fast_mblock_alloc_init_func init_func,
        void *init_args, const bool need_lock)
Y
yuqing 已提交
192 193
{
    return fast_mblock_init_ex2(mblock, name, element_size,
194 195
            alloc_elements_once, alloc_elements_limit, init_func,
            init_args, need_lock, NULL, NULL, NULL);
Y
yuqing 已提交
196
}
Y
yuqing 已提交
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217

/**
mblock destroy
parameters:
	mblock: the mblock pointer
*/
void fast_mblock_destroy(struct fast_mblock_man *mblock);

/**
alloc a node from the mblock
parameters:
	mblock: the mblock pointer
return the alloced node, return NULL if fail
*/
struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock);

/**
free a node (put a node to the mblock)
parameters:
	mblock: the mblock pointer
	pNode: the node to free
218
return 0 for success, return none zero if fail
Y
yuqing 已提交
219
*/
220
int fast_mblock_free(struct fast_mblock_man *mblock,
Y
yuqing 已提交
221 222
		     struct fast_mblock_node *pNode);

Y
yuqing 已提交
223 224 225 226 227 228 229 230 231 232 233
/**
delay free a node (put a node to the mblock)
parameters:
	mblock: the mblock pointer
	pNode: the node to free
    delay: delay seconds to free
return 0 for success, return none zero if fail
*/
int fast_mblock_delay_free(struct fast_mblock_man *mblock,
		     struct fast_mblock_node *pNode, const int delay);

234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
/**
alloc a object from the mblock
parameters:
	mblock: the mblock pointer
return the alloced object, return NULL if fail
*/
static inline void *fast_mblock_alloc_object(struct fast_mblock_man *mblock)
{
    struct fast_mblock_node *node;
    node = fast_mblock_alloc(mblock);
    if (node == NULL)
    {
        return NULL;
    }
    return node->data;
}

/**
free a object (put the object to the mblock)
parameters:
	mblock: the mblock pointer
	object: the object to free
return 0 for success, return none zero if fail
*/
static inline int fast_mblock_free_object(struct fast_mblock_man *mblock,
        void *object)
{
    return fast_mblock_free(mblock, fast_mblock_to_node_ptr(object));
}

Y
yuqing 已提交
264 265 266 267 268 269 270 271
/**
delay free a object (put a node to the mblock)
parameters:
	mblock: the mblock pointer
	pNode: the node to free
    delay: delay seconds to free
return 0 for success, return none zero if fail
*/
Y
yuqing 已提交
272
static inline int fast_mblock_delay_free_object(struct fast_mblock_man *mblock,
Y
yuqing 已提交
273 274 275 276 277
        void *object, const int delay)
{
    return fast_mblock_delay_free(mblock, fast_mblock_to_node_ptr(object), delay);
}

Y
yuqing 已提交
278 279 280 281 282 283
/**
get node count of the mblock
parameters:
	mblock: the mblock pointer
return the free node count of the mblock, return -1 if fail
*/
Y
yuqing 已提交
284 285
int fast_mblock_free_count(struct fast_mblock_man *mblock);

Y
yuqing 已提交
286 287 288 289 290 291 292 293
/**
get delay free node count of the mblock
parameters:
	mblock: the mblock pointer
return the delay free node count of the mblock, return -1 if fail
*/
int fast_mblock_delay_free_count(struct fast_mblock_man *mblock);

Y
yuqing 已提交
294
#define fast_mblock_total_count(mblock) (mblock)->total_count
Y
yuqing 已提交
295

Y
yuqing 已提交
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
/**
init mblock manager
parameters:
return error no, 0 for success, != 0 fail
*/
int fast_mblock_manager_init();

/**
get mblock stat
parameters:
    stats: return mblock stats
    size: max size of stats
    count: return mblock stat count
return error no, 0 for success, != 0 fail
*/
int fast_mblock_manager_stat(struct fast_mblock_info *stats,
        const int size, int *count);


/**
print mblock manager stat
parameters:
Y
Yu Qing 已提交
318
    hide_empty: if hide empty
Y
yuqing 已提交
319
    order_by: order by which field
Y
yuqing 已提交
320 321
return error no, 0 for success, != 0 fail
*/
Y
yuqing 已提交
322 323 324 325
int fast_mblock_manager_stat_print_ex(const bool hide_empty, const int order_by);

#define fast_mblock_manager_stat_print(hide_empty) \
        fast_mblock_manager_stat_print_ex(hide_empty, FAST_MBLOCK_ORDER_BY_ALLOC_BYTES)
Y
yuqing 已提交
326

Y
yuqing 已提交
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
typedef void (*fast_mblock_free_trunks_func)(struct fast_mblock_man *mblock,
        struct fast_mblock_malloc *freelist);

/**
free the trunks
parameters:
	mblock: the mblock pointer
    freelist: the trunks to free
return error no, 0 for success, != 0 fail
*/
void fast_mblock_free_trunks(struct fast_mblock_man *mblock,
        struct fast_mblock_malloc *freelist);

/**
reclaim the free trunks of the mblock
parameters:
Y
Yu Qing 已提交
343 344
    mblock: the mblock pointer
    reclaim_target: reclaim target trunks, 0 for no limit
Y
yuqing 已提交
345 346 347 348 349 350 351 352
    reclaim_count: reclaimed trunk count
    freelist: the free trunks
return error no, 0 for success, != 0 fail
*/
int fast_mblock_reclaim(struct fast_mblock_man *mblock,
        const int reclaim_target, int *reclaim_count,
        fast_mblock_free_trunks_func free_trunks_func);

Y
yuqing 已提交
353 354 355 356 357 358
#ifdef __cplusplus
}
#endif

#endif