1 /*
2  * Copyright (c) 2014-2017, Siemens AG. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef EMBB_BASE_C_MEMORY_ALLOCATION_H_
28 #define EMBB_BASE_C_MEMORY_ALLOCATION_H_
29 
30 /**
31 * \defgroup C_BASE_ALLOC Memory Allocation
32 *
33 * \ingroup C_BASE
34 *
35 * Functions for dynamic memory allocation
36 *
37 * There are functions for aligned and unaligned memory allocation. In debug
38 * mode, memory usage is tracked to detect memory leaks.
39 */
40 
41 #include <stdlib.h>
42 #include <embb/base/c/internal/config.h>
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif // __cplusplus
47 
48   /**
49    * Allocates \p size bytes of memory.
50    *
51    * Keeps track of allocated memory in debug mode.
52    *
53    * \return NULL in case of failure, otherwise address of allocated memory
54    * block.
55    *
56    * \memory <tt>size+3*sizeof(size_t)</tt> bytes in debug mode, otherwise \c
57    *         size bytes
58    *
59    * \threadsafe
60    *
61    * \see embb_get_bytes_allocated()
62    *
63    * \ingroup C_BASE_ALLOC
64    */
65   void* embb_alloc(
66     size_t size
67     /**< [IN] Size of memory block to be allocated in bytes */
68     );
69 
70   /**
71    * Frees memory that has been allocated by embb_alloc() for some pointer
72    * \p ptr.
73    *
74    * Keeps track of freed memory in debug mode.
75    *
76    * \pre \c ptr is not NULL.
77    *
78    * \threadsafe
79    *
80    * \see embb_get_bytes_allocated()
81    *
82    * \ingroup C_BASE_ALLOC
83    */
84   void embb_free(
85     void* ptr
86     /**< [IN,OUT] Pointer to memory block to be freed */
87     );
88 
89   /**
90    * Allocates \p size bytes of memory with alignment \p alignment.
91    *
92    * This function can be used to align objects to certain boundaries such as
93    * cache lines, memory pages, etc.
94    *
95    * Keeps track of allocated memory in debug mode.
96    *
97    * It is not required that \p size is a multiple of \p alignment as, e.g.,
98    * for the \c aligned\_alloc function of the C11 standard.
99    *
100    * \pre The alignment has to be power of 2 and a multiple of
101    *      <tt>size(void*)</tt>.
102    * \post The returned pointer is a multiple of \p alignment.
103    *
104    * \return NULL in case of failure, otherwise address of allocated memory
105    * block.
106    *
107    * \memory Debug mode: Let \c n be the number of aligned cells necessary to
108    *         fit the payload. Then, <tt>(n+1)*alignment+3*size_of(size_t)-1</tt>
109    *         bytes are allocated.<br> Release mode: \c size bytes are requested
110    *         using the functions provided by the operating systems.
111    *
112    * \threadsafe
113    *
114    * \note Memory allocated using this function must be freed using
115    *       embb_free_aligned().
116    *
117    * \see embb_alloc_cache_aligned(), embb_free_aligned(),
118    *      embb_get_bytes_allocated()
119    *
120    * \ingroup C_BASE_ALLOC
121    */
122   void* embb_alloc_aligned(
123     size_t alignment,
124     /**< [IN] Alignment in bytes */
125     size_t size
126     /**< [IN] Size of memory block to be allocated in bytes */
127     );
128 
129   /**
130    * Allocates \p size bytes of cache-aligned memory.
131    *
132    * Specialized version of embb_alloc_aligned(). The alignment is chosen
133    * automatically (usually 64 bytes).
134    *
135    * Keeps track of allocated memory in debug mode.
136    *
137    * \post The returned pointer is a multiple of the cache line size.
138    *
139    * \return NULL in case of failure, otherwise address of allocated memory
140    *         block.
141    *
142    * \memory See embb_alloc_aligned()
143    *
144    * \threadsafe
145    *
146    * \note Memory allocated using this function must be freed using
147    *       embb_free_aligned().
148    *
149    * \see embb_alloc_aligned(), embb_free_aligned(), embb_get_bytes_allocated()
150    *
151    * \ingroup C_BASE_ALLOC
152    */
153   void* embb_alloc_cache_aligned(
154     size_t size
155     /**< [IN] Size of memory block to be allocated in bytes */
156     );
157 
158   /**
159    * Frees memory that has been allocated by an aligned method for \c ptr.
160    *
161    * The available aligned methods are embb_alloc_aligned() or
162    * embb_alloc_cache_aligned().
163    *
164    * Keeps track of freed memory in debug mode.
165    *
166    * \pre \c ptr is not NULL and was allocated by an aligned method.
167    *
168    * \threadsafe
169    *
170    * \see embb_alloc_aligned(), embb_alloc_cache_aligned(),
171    *      embb_get_bytes_allocated()
172    *
173    * \ingroup C_BASE_ALLOC
174    */
175   void embb_free_aligned(
176     void* ptr
177     /**< [IN,OUT] Pointer to memory block to be freed */
178     );
179 
180   /**
181    * Returns the total number of bytes currently allocated.
182    *
183    * Only the bytes allocated by embb_alloc(), embb_alloc_aligned(), and
184    * embb_alloc_cache_aligned() in debug mode are counted.
185    *
186    * \return Number of currently allocated bytes in debug mode, otherwise 0.
187    *
188    * \waitfree
189    *
190    * \see embb_alloc(), embb_alloc_aligned(), embb_alloc_cache_aligned()
191    *
192    * \ingroup C_BASE_ALLOC
193    */
194   size_t embb_get_bytes_allocated();
195 #ifdef __cplusplus
196 }
197 #endif // __cplusplus
198 
199 #endif // EMBB_BASE_C_MEMORY_ALLOCATION_H_
200