1
2 #ifndef __XMALLOC_H__
3 #define __XMALLOC_H__
4
5 #include <xen/types.h>
6 #include <xen/cache.h>
7
8 /*
9 * Xen malloc/free-style interface.
10 *
11 * NOTE: Unless physically contiguous memory space is required, the interfaces
12 * in xvmalloc.h are to be used in preference to the ones here.
13 */
14
15 /* Allocate space for typed object. */
16 #define xmalloc(_type) ((_type *)_xmalloc(sizeof(_type), __alignof__(_type)))
17 #define xzalloc(_type) ((_type *)_xzalloc(sizeof(_type), __alignof__(_type)))
18
19 /*
20 * Allocate space for a typed object and copy an existing instance.
21 *
22 * Note: Due to const propagating in the typeof(), ptr needs to be mutable.
23 * This can be fixed by changing n_ to being void *, but then we lose type
24 * safety on the return value.
25 */
26 #define xmemdup(ptr) \
27 ({ \
28 typeof(*(ptr)) *p_ = (ptr), *n_ = xmalloc(typeof(*p_)); \
29 \
30 if ( n_ ) \
31 memcpy(n_, p_, sizeof(*n_)); \
32 n_; \
33 })
34
35 /* Allocate space for array of typed objects. */
36 #define xmalloc_array(_type, _num) \
37 ((_type *)_xmalloc_array(sizeof(_type), __alignof__(_type), _num))
38 #define xzalloc_array(_type, _num) \
39 ((_type *)_xzalloc_array(sizeof(_type), __alignof__(_type), _num))
40 #define xrealloc_array(_ptr, _num) \
41 ((typeof(_ptr))_xrealloc_array(_ptr, sizeof(typeof(*(_ptr))), \
42 __alignof__(typeof(*(_ptr))), _num))
43
44 /* Allocate space for a structure with a flexible array of typed objects. */
45 #define xzalloc_flex_struct(type, field, nr) \
46 ((type *)_xzalloc(offsetof(type, field[nr]), __alignof__(type)))
47
48 #define xmalloc_flex_struct(type, field, nr) \
49 ((type *)_xmalloc(offsetof(type, field[nr]), __alignof__(type)))
50
51 /* Re-allocate space for a structure with a flexible array of typed objects. */
52 #define xrealloc_flex_struct(ptr, field, nr) \
53 ((typeof(ptr))_xrealloc(ptr, offsetof(typeof(*(ptr)), field[nr]), \
54 __alignof__(typeof(*(ptr)))))
55
56 /* Allocate untyped storage. */
57 #define xmalloc_bytes(_bytes) _xmalloc(_bytes, SMP_CACHE_BYTES)
58 #define xzalloc_bytes(_bytes) _xzalloc(_bytes, SMP_CACHE_BYTES)
59
60 /* Allocate untyped storage and copying an existing instance. */
61 #define xmemdup_bytes(_src, _nr) \
62 ({ \
63 unsigned long nr_ = (_nr); \
64 void *dst_ = xmalloc_bytes(nr_); \
65 \
66 if ( dst_ ) \
67 memcpy(dst_, _src, nr_); \
68 dst_; \
69 })
70
71 /* Free any of the above. */
72 extern void xfree(void *p);
73
74 /* Free an allocation, and zero the pointer to it. */
75 #define XFREE(p) do { \
76 void *_ptr_ = (p); \
77 (p) = NULL; \
78 xfree(_ptr_); \
79 } while ( false )
80
81 /* Underlying functions */
82 extern void *_xmalloc(unsigned long size, unsigned long align);
83 extern void *_xzalloc(unsigned long size, unsigned long align);
84 extern void *_xrealloc(void *ptr, unsigned long size, unsigned long align);
85
_xmalloc_array(unsigned long size,unsigned long align,unsigned long num)86 static inline void *_xmalloc_array(
87 unsigned long size, unsigned long align, unsigned long num)
88 {
89 /* Check for overflow. */
90 if ( size && num > UINT_MAX / size )
91 return NULL;
92 return _xmalloc(size * num, align);
93 }
94
_xzalloc_array(unsigned long size,unsigned long align,unsigned long num)95 static inline void *_xzalloc_array(
96 unsigned long size, unsigned long align, unsigned long num)
97 {
98 /* Check for overflow. */
99 if ( size && num > UINT_MAX / size )
100 return NULL;
101 return _xzalloc(size * num, align);
102 }
103
_xrealloc_array(void * ptr,unsigned long size,unsigned long align,unsigned long num)104 static inline void *_xrealloc_array(
105 void *ptr, unsigned long size, unsigned long align, unsigned long num)
106 {
107 /* Check for overflow. */
108 if ( size && num > UINT_MAX / size )
109 return NULL;
110 return _xrealloc(ptr, size * num, align);
111 }
112
113 /*
114 * Pooled allocator interface.
115 */
116
117 struct xmem_pool;
118
119 typedef void *(xmem_pool_get_memory)(unsigned long bytes);
120 typedef void (xmem_pool_put_memory)(void *ptr);
121
122 /**
123 * xmem_pool_create - create dynamic memory pool
124 * @name: name of the pool
125 * @get_mem: callback function used to expand pool
126 * @put_mem: callback function used to shrink pool
127 * @max_size: maximum pool size (in bytes) - set this as 0 for no limit
128 * @grow_size: amount of memory (in bytes) added to pool whenever required
129 *
130 * All size values are rounded up to next page boundary.
131 */
132 struct xmem_pool *xmem_pool_create(
133 const char *name,
134 xmem_pool_get_memory get_mem,
135 xmem_pool_put_memory put_mem,
136 unsigned long max_size,
137 unsigned long grow_size);
138
139 /**
140 * xmem_pool_destroy - cleanup given pool
141 * @mem_pool: Pool to be destroyed
142 *
143 * Data structures associated with pool are freed.
144 * All memory allocated from pool must be freed before
145 * destorying it.
146 */
147 void xmem_pool_destroy(struct xmem_pool *pool);
148
149 /**
150 * xmem_pool_alloc - allocate memory from given pool
151 * @size: no. of bytes
152 * @mem_pool: pool to allocate from
153 */
154 void *xmem_pool_alloc(unsigned long size, struct xmem_pool *pool);
155
156 /**
157 * xmem_pool_maxalloc - xmem_pool_alloc's greater than this size will fail
158 * @mem_pool: pool
159 */
160 int xmem_pool_maxalloc(struct xmem_pool *pool);
161
162 /**
163 * xmem_pool_maxsize -
164 * @ptr: address of memory to be freed
165 * @mem_pool: pool to free from
166 */
167 void xmem_pool_free(void *ptr, struct xmem_pool *pool);
168
169 /**
170 * xmem_pool_get_used_size - get memory currently used by given pool
171 *
172 * Used memory includes stored data + metadata + internal fragmentation
173 */
174 unsigned long xmem_pool_get_used_size(struct xmem_pool *pool);
175
176 /**
177 * xmem_pool_get_total_size - get total memory currently allocated for pool
178 *
179 * This is the total memory currently allocated for this pool which includes
180 * used size + free size.
181 *
182 * (Total - Used) is good indicator of memory efficiency of allocator.
183 */
184 unsigned long xmem_pool_get_total_size(struct xmem_pool *pool);
185
186 #endif /* __XMALLOC_H__ */
187