FD.io VPP  v16.06
Vector Packet Processing
mem.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17 
18  Permission is hereby granted, free of charge, to any person obtaining
19  a copy of this software and associated documentation files (the
20  "Software"), to deal in the Software without restriction, including
21  without limitation the rights to use, copy, modify, merge, publish,
22  distribute, sublicense, and/or sell copies of the Software, and to
23  permit persons to whom the Software is furnished to do so, subject to
24  the following conditions:
25 
26  The above copyright notice and this permission notice shall be
27  included in all copies or substantial portions of the Software.
28 
29  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 */
37 
38 #ifndef _included_clib_mem_h
39 #define _included_clib_mem_h
40 
41 #include <stdarg.h>
42 
43 #include <vppinfra/clib.h> /* uword, etc */
45 #include <vppinfra/os.h>
46 #include <vppinfra/string.h> /* memcpy, memset */
47 #include <vppinfra/valgrind.h>
48 
49 #define CLIB_MAX_MHEAPS 256
50 
51 /* Per CPU heaps. */
53 
55 {
56  int cpu = os_get_cpu_number ();
57  return clib_per_cpu_mheaps[cpu];
58 }
59 
61 {
62  int cpu = os_get_cpu_number ();
63  void * old = clib_per_cpu_mheaps[cpu];
64  clib_per_cpu_mheaps[cpu] = new_heap;
65  return old;
66 }
67 
68 /* Memory allocator which returns null when it fails. */
69 always_inline void *
71  uword align,
72  uword align_offset)
73 {
74  void * heap, * p;
75  uword offset, cpu;
76 
77  if (align_offset > align)
78  {
79  if (align > 0)
80  align_offset %= align;
81  else
82  align_offset = align;
83  }
84 
85  cpu = os_get_cpu_number ();
86  heap = clib_per_cpu_mheaps[cpu];
87  heap = mheap_get_aligned (heap,
88  size, align, align_offset,
89  &offset);
90  clib_per_cpu_mheaps[cpu] = heap;
91 
92  if (offset != ~0)
93  {
94  p = heap + offset;
95 #if CLIB_DEBUG > 0
96  VALGRIND_MALLOCLIKE_BLOCK (p, mheap_data_bytes (heap, offset), 0, 0);
97 #endif
98  return p;
99  }
100  else
101  {
102  os_out_of_memory ();
103  return 0;
104  }
105 }
106 
107 /* Memory allocator which returns null when it fails. */
108 always_inline void *
110 { return clib_mem_alloc_aligned_at_offset (size, /* align */ 1, /* align_offset */ 0); }
111 
112 always_inline void *
114 { return clib_mem_alloc_aligned_at_offset (size, align, /* align_offset */ 0); }
115 
116 /* Memory allocator which panics when it fails.
117  Use macro so that clib_panic macro can expand __FUNCTION__ and __LINE__. */
118 #define clib_mem_alloc_aligned_no_fail(size,align) \
119 ({ \
120  uword _clib_mem_alloc_size = (size); \
121  void * _clib_mem_alloc_p; \
122  _clib_mem_alloc_p = clib_mem_alloc_aligned (_clib_mem_alloc_size, (align)); \
123  if (! _clib_mem_alloc_p) \
124  clib_panic ("failed to allocate %d bytes", _clib_mem_alloc_size); \
125  _clib_mem_alloc_p; \
126 })
127 
128 #define clib_mem_alloc_no_fail(size) clib_mem_alloc_aligned_no_fail(size,1)
129 
130 /* Alias to stack allocator for naming consistency. */
131 #define clib_mem_alloc_stack(bytes) __builtin_alloca(bytes)
132 
134 {
135  void * heap = clib_mem_get_per_cpu_heap ();
136  uword offset = (uword)p - (uword)heap;
137  mheap_elt_t * e, * n;
138 
139  if (offset >= vec_len (heap))
140  return 0;
141 
142  e = mheap_elt_at_uoffset (heap, offset);
143  n = mheap_next_elt (e);
144 
145  /* Check that heap forward and reverse pointers agree. */
146  return e->n_user_data == n->prev_n_user_data;
147 }
148 
150 {
151  u8 * heap = clib_mem_get_per_cpu_heap ();
152 
153  /* Make sure object is in the correct heap. */
155 
156  mheap_put (heap, (u8 *) p - heap);
157 
158 #if CLIB_DEBUG > 0
160 #endif
161 }
162 
163 always_inline void * clib_mem_realloc (void * p, uword new_size, uword old_size)
164 {
165  /* By default use alloc, copy and free to emulate realloc. */
166  void * q = clib_mem_alloc (new_size);
167  if (q)
168  {
169  uword copy_size;
170  if (old_size < new_size)
171  copy_size = old_size;
172  else
173  copy_size = new_size;
174  clib_memcpy (q, p, copy_size);
175  clib_mem_free (p);
176  }
177  return q;
178 }
179 
181 {
184  return mheap_elt_data_bytes (e);
185 }
186 
188 { return clib_mem_get_per_cpu_heap (); }
189 
190 always_inline void * clib_mem_set_heap (void * heap)
191 { return clib_mem_set_per_cpu_heap (heap); }
192 
193 void * clib_mem_init (void * heap, uword size);
194 
195 void clib_mem_exit (void);
196 
198 
199 void clib_mem_validate (void);
200 
201 void clib_mem_trace (int enable);
202 
203 typedef struct {
204  /* Total number of objects allocated. */
206 
207  /* Total allocated bytes. Bytes used and free.
208  used + free = total */
209  uword bytes_total, bytes_used, bytes_free;
210 
211  /* Number of bytes used by mheap data structure overhead
212  (e.g. free lists, mheap header). */
214 
215  /* Amount of free space returned to operating system. */
217 
218  /* For malloc which puts small objects in sbrk region and
219  large objects in mmap'ed regions. */
222 
223  /* Max. number of bytes in this heap. */
226 
228 
229 u8 * format_clib_mem_usage (u8 * s, va_list * args);
230 
231 /* Include appropriate VM functions depending on whether
232  we are compiling for linux kernel, for Unix or standalone. */
233 #ifdef CLIB_LINUX_KERNEL
235 #endif
236 
237 #ifdef CLIB_UNIX
238 #include <vppinfra/vm_unix.h>
239 #endif
240 
241 #ifdef CLIB_STANDALONE
242 #include <vppinfra/vm_standalone.h>
243 #endif
244 
245 #include <vppinfra/error.h> /* clib_panic */
246 
247 #endif /* _included_clib_mem_h */
uword bytes_overhead
Definition: mem.h:213
void clib_mem_validate(void)
Definition: mem_mheap.c:133
always_inline mheap_elt_t * mheap_user_pointer_to_elt(void *v)
void * clib_per_cpu_mheaps[CLIB_MAX_MHEAPS]
Definition: mem_mheap.c:53
always_inline void * clib_mem_alloc_aligned_at_offset(uword size, uword align, uword align_offset)
Definition: mem.h:70
uword bytes_free_reclaimed
Definition: mem.h:216
always_inline void clib_mem_free(void *p)
Definition: mem.h:149
void os_out_of_memory(void)
Definition: unix-misc.c:202
always_inline uword mheap_data_bytes(void *v, uword uo)
static void usage(void)
Definition: health_check.c:14
uword bytes_used_sbrk
Definition: mem.h:220
always_inline void * clib_mem_realloc(void *p, uword new_size, uword old_size)
Definition: mem.h:163
#define CLIB_MAX_MHEAPS
Definition: mem.h:49
always_inline void * clib_mem_set_per_cpu_heap(u8 *new_heap)
Definition: mem.h:60
uword bytes_used
Definition: mem.h:209
uword object_count
Definition: mem.h:205
always_inline void * clib_mem_get_per_cpu_heap(void)
Definition: mem.h:54
always_inline uword clib_mem_size(void *p)
Definition: mem.h:180
#define always_inline
Definition: clib.h:84
always_inline void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:113
uword os_get_cpu_number(void)
Definition: unix-misc.c:206
u8 * format_clib_mem_usage(u8 *s, va_list *args)
Definition: mem_mheap.c:121
uword bytes_used_mmap
Definition: mem.h:221
always_inline void * clib_mem_set_heap(void *heap)
Definition: mem.h:190
always_inline void * clib_mem_get_heap(void)
Definition: mem.h:187
always_inline uword mheap_elt_data_bytes(mheap_elt_t *e)
void * clib_mem_init(void *heap, uword size)
Definition: mem_mheap.c:65
always_inline void * clib_mem_alloc(uword size)
Definition: mem.h:109
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)
Definition: valgrind.h:3894
void * mheap_get_aligned(void *v, uword n_user_data_bytes, uword align, uword align_offset, uword *offset_return)
Definition: mheap.c:621
uword bytes_max
Definition: mem.h:224
#define clib_memcpy(a, b, c)
Definition: string.h:63
always_inline mheap_elt_t * mheap_next_elt(mheap_elt_t *e)
#define ASSERT(truth)
always_inline mheap_elt_t * mheap_elt_at_uoffset(void *v, uword uo)
u32 size
Definition: vhost-user.h:74
u64 uword
Definition: types.h:112
always_inline uword clib_mem_is_heap_object(void *p)
Definition: mem.h:133
void mheap_put(void *v, uword uoffset)
Definition: mheap.c:728
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
void clib_mem_usage(clib_mem_usage_t *usage)
Definition: mem_mheap.c:127
#define VALGRIND_FREELIKE_BLOCK(addr, rzB)
Definition: valgrind.h:3905
void clib_mem_trace(int enable)
Definition: mem_mheap.c:144
uword clib_mem_get_page_size(void)
Definition: mem_mheap.c:111
void clib_mem_exit(void)
Definition: mem_mheap.c:55