1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #ifndef ZABBIX_MEMALLOC_H
21 #define ZABBIX_MEMALLOC_H
22 
23 #include "common.h"
24 #include "mutexs.h"
25 
26 #define MEM_MIN_ALLOC	24	/* should be a multiple of 8 and at least (2 * ZBX_PTR_SIZE) */
27 
28 #define MEM_MIN_BUCKET_SIZE	MEM_MIN_ALLOC
29 #define MEM_MAX_BUCKET_SIZE	256 /* starting from this size all free chunks are put into the same bucket */
30 #define MEM_BUCKET_COUNT	((MEM_MAX_BUCKET_SIZE - MEM_MIN_BUCKET_SIZE) / 8 + 1)
31 
32 typedef struct
33 {
34 	void		**buckets;
35 	void		*lo_bound;
36 	void		*hi_bound;
37 	zbx_uint64_t	free_size;
38 	zbx_uint64_t	used_size;
39 	zbx_uint64_t	orig_size;
40 	zbx_uint64_t	total_size;
41 	int		shm_id;
42 
43 	/* Continue execution in out of memory situation.                         */
44 	/* Normally allocator forces exit when it runs out of allocatable memory. */
45 	/* Set this flag to 1 to allow execution in out of memory situations.     */
46 	char		allow_oom;
47 
48 	const char	*mem_descr;
49 	const char	*mem_param;
50 }
51 zbx_mem_info_t;
52 
53 typedef struct
54 {
55 	zbx_uint64_t	free_size;
56 	zbx_uint64_t	used_size;
57 	zbx_uint64_t	min_chunk_size;
58 	zbx_uint64_t	max_chunk_size;
59 	zbx_uint64_t	overhead;
60 	unsigned int	chunks_num[MEM_BUCKET_COUNT];
61 	unsigned int	free_chunks;
62 	unsigned int	used_chunks;
63 }
64 zbx_mem_stats_t;
65 
66 int	zbx_mem_create(zbx_mem_info_t **info, zbx_uint64_t size, const char *descr, const char *param, int allow_oom,
67 		char **error);
68 
69 #define	zbx_mem_malloc(info, old, size) __zbx_mem_malloc(__FILE__, __LINE__, info, old, size)
70 #define	zbx_mem_realloc(info, old, size) __zbx_mem_realloc(__FILE__, __LINE__, info, old, size)
71 #define	zbx_mem_free(info, ptr)				\
72 							\
73 do							\
74 {							\
75 	__zbx_mem_free(__FILE__, __LINE__, info, ptr);	\
76 	ptr = NULL;					\
77 }							\
78 while (0)
79 
80 void	*__zbx_mem_malloc(const char *file, int line, zbx_mem_info_t *info, const void *old, size_t size);
81 void	*__zbx_mem_realloc(const char *file, int line, zbx_mem_info_t *info, void *old, size_t size);
82 void	__zbx_mem_free(const char *file, int line, zbx_mem_info_t *info, void *ptr);
83 
84 void	zbx_mem_clear(zbx_mem_info_t *info);
85 
86 void	zbx_mem_get_stats(const zbx_mem_info_t *info, zbx_mem_stats_t *stats);
87 void	zbx_mem_dump_stats(int level, zbx_mem_info_t *info);
88 
89 size_t	zbx_mem_required_size(int chunks_num, const char *descr, const char *param);
90 zbx_uint64_t	zbx_mem_required_chunk_size(zbx_uint64_t size);
91 
92 #define ZBX_MEM_FUNC1_DECL_MALLOC(__prefix)				\
93 static void	*__prefix ## _mem_malloc_func(void *old, size_t size)
94 #define ZBX_MEM_FUNC1_DECL_REALLOC(__prefix)				\
95 static void	*__prefix ## _mem_realloc_func(void *old, size_t size)
96 #define ZBX_MEM_FUNC1_DECL_FREE(__prefix)				\
97 static void	__prefix ## _mem_free_func(void *ptr)
98 
99 #define ZBX_MEM_FUNC1_IMPL_MALLOC(__prefix, __info)			\
100 									\
101 static void	*__prefix ## _mem_malloc_func(void *old, size_t size)	\
102 {									\
103 	return zbx_mem_malloc(__info, old, size);			\
104 }
105 
106 #define ZBX_MEM_FUNC1_IMPL_REALLOC(__prefix, __info)			\
107 									\
108 static void	*__prefix ## _mem_realloc_func(void *old, size_t size)	\
109 {									\
110 	return zbx_mem_realloc(__info, old, size);			\
111 }
112 
113 #define ZBX_MEM_FUNC1_IMPL_FREE(__prefix, __info)			\
114 									\
115 static void	__prefix ## _mem_free_func(void *ptr)			\
116 {									\
117 	zbx_mem_free(__info, ptr);					\
118 }
119 
120 #define ZBX_MEM_FUNC_DECL(__prefix)					\
121 									\
122 ZBX_MEM_FUNC1_DECL_MALLOC(__prefix);					\
123 ZBX_MEM_FUNC1_DECL_REALLOC(__prefix);					\
124 ZBX_MEM_FUNC1_DECL_FREE(__prefix);
125 
126 #define ZBX_MEM_FUNC_IMPL(__prefix, __info)				\
127 									\
128 ZBX_MEM_FUNC1_IMPL_MALLOC(__prefix, __info)				\
129 ZBX_MEM_FUNC1_IMPL_REALLOC(__prefix, __info)				\
130 ZBX_MEM_FUNC1_IMPL_FREE(__prefix, __info)
131 
132 #endif
133