1 | /* |
2 | * HeapMempory.hpp |
3 | * |
4 | * Created on: Aug 17, 2014 |
5 | * Author: Pietro Incardona |
6 | */ |
7 | |
8 | #ifndef HEAP_MEMORY_HPP |
9 | #define HEAP_MEMORY_HPP |
10 | |
11 | #include "config.h" |
12 | #include "memory.hpp" |
13 | #include <cstddef> |
14 | #include <cstdint> |
15 | #include <iostream> |
16 | |
17 | typedef unsigned char byte; |
18 | |
19 | #define MEM_ALIGNMENT 32 |
20 | |
21 | |
22 | /** |
23 | * \brief This class allocate, and destroy CPU memory |
24 | * |
25 | * |
26 | * ### Allocate memory |
27 | * |
28 | * \snippet HeapMemory_unit_tests.hpp Allocate some memory and fill with data |
29 | * |
30 | * ### Resize memory |
31 | * |
32 | * \snippet HeapMemory_unit_tests.hpp Resize the memory |
33 | * |
34 | * ### Shrink memory |
35 | * |
36 | * \snippet HeapMemory_unit_tests.hpp Shrink memory |
37 | * |
38 | */ |
39 | class HeapMemory : public memory |
40 | { |
41 | //! memory alignment |
42 | size_t alignement; |
43 | |
44 | //! Size of the memory |
45 | size_t sz; |
46 | |
47 | //! device memory |
48 | byte * dm; |
49 | //! original pointer (before alignment) |
50 | byte * dmOrig; |
51 | //! Reference counter |
52 | long int ref_cnt; |
53 | |
54 | //! copy from Pointer to Heap |
55 | bool copyFromPointer(const void * ptr, size_t sz); |
56 | |
57 | //! Set alignment the memory will be aligned with this number |
58 | void setAlignment(size_t align); |
59 | |
60 | public: |
61 | |
62 | //! copy from same Heap to Heap |
63 | bool copyDeviceToDevice(const HeapMemory & m); |
64 | |
65 | //! flush the memory |
66 | virtual bool flush() {return true;}; |
67 | //! allocate memory |
68 | virtual bool allocate(size_t sz); |
69 | //! destroy memory |
70 | virtual void destroy(); |
71 | //! copy memory |
72 | virtual bool copy(const memory & m); |
73 | //! the the size of the allocated memory |
74 | virtual size_t size() const; |
75 | //! resize the memory allocated |
76 | virtual bool resize(size_t sz); |
77 | //! get a readable pointer with the data |
78 | virtual void * getPointer(); |
79 | |
80 | //! get a readable pointer with the data |
81 | virtual const void * getPointer() const; |
82 | |
83 | //! get a device pointer for HeapMemory getPointer and getDevicePointer are equivalents |
84 | virtual void * getDevicePointer(); |
85 | |
86 | /*! \brief fill host and device memory with the selected byte |
87 | * |
88 | * |
89 | */ |
90 | virtual void fill(unsigned char c); |
91 | |
92 | //! Do nothing |
93 | virtual void hostToDevice(){}; |
94 | |
95 | //! Do nothing |
96 | virtual void deviceToHost(){}; |
97 | |
98 | //! Do nothing |
99 | virtual void deviceToHost(size_t start, size_t stop) {}; |
100 | |
101 | //! Do nothing |
102 | virtual void hostToDevice(size_t start, size_t stop) {}; |
103 | |
104 | //! Increment the reference counter |
105 | virtual void incRef() |
106 | {ref_cnt++;} |
107 | |
108 | //! Decrement the reference counter |
109 | virtual void decRef() |
110 | {ref_cnt--;} |
111 | |
112 | //! Return the reference counter |
113 | virtual long int ref() |
114 | { |
115 | return ref_cnt; |
116 | } |
117 | |
118 | /*! \brief Allocated Memory is never initialized |
119 | * |
120 | * \return false |
121 | * |
122 | */ |
123 | bool isInitialized() |
124 | { |
125 | return false; |
126 | } |
127 | |
128 | // Copy the Heap memory |
129 | HeapMemory & operator=(const HeapMemory & mem) |
130 | { |
131 | copy(mem); |
132 | return *this; |
133 | } |
134 | |
135 | // Copy the Heap memory |
136 | HeapMemory(const HeapMemory & mem) |
137 | :HeapMemory() |
138 | { |
139 | allocate(mem.size()); |
140 | copy(mem); |
141 | } |
142 | |
143 | HeapMemory(HeapMemory && mem) noexcept |
144 | { |
145 | //! move |
146 | alignement = mem.alignement; |
147 | sz = mem.sz; |
148 | dm = mem.dm; |
149 | dmOrig = mem.dmOrig; |
150 | ref_cnt = mem.ref_cnt; |
151 | |
152 | mem.alignement = MEM_ALIGNMENT; |
153 | mem.sz = 0; |
154 | mem.dm = NULL; |
155 | mem.dmOrig = NULL; |
156 | mem.ref_cnt = 0; |
157 | } |
158 | |
159 | //! Constructor, we choose a default alignment of 32 for avx |
160 | HeapMemory():alignement(MEM_ALIGNMENT),sz(0),dm(NULL),dmOrig(NULL),ref_cnt(0) {}; |
161 | |
162 | virtual ~HeapMemory() noexcept |
163 | { |
164 | if(ref_cnt == 0) |
165 | HeapMemory::destroy(); |
166 | else |
167 | std::cerr << "Error: " << __FILE__ << " " << __LINE__ << " destroying a live object" << "\n" ; |
168 | }; |
169 | |
170 | /*! \brief Swap the memory |
171 | * |
172 | * \param mem memory to swap |
173 | * |
174 | */ |
175 | void swap(HeapMemory & mem) |
176 | { |
177 | size_t alignement_tmp; |
178 | size_t sz_tmp; |
179 | byte * dm_tmp; |
180 | byte * dmOrig_tmp; |
181 | long int ref_cnt_tmp; |
182 | |
183 | alignement_tmp = alignement; |
184 | sz_tmp = sz; |
185 | dm_tmp = dm; |
186 | dmOrig_tmp = dmOrig; |
187 | ref_cnt_tmp = ref_cnt; |
188 | |
189 | alignement = mem.alignement; |
190 | sz = mem.sz; |
191 | dm = mem.dm; |
192 | dmOrig = mem.dmOrig; |
193 | ref_cnt = mem.ref_cnt; |
194 | |
195 | mem.alignement = alignement_tmp; |
196 | mem.sz = sz_tmp; |
197 | mem.dm = dm_tmp; |
198 | mem.dmOrig = dmOrig_tmp; |
199 | mem.ref_cnt = ref_cnt_tmp; |
200 | } |
201 | |
202 | /*! \brief Return true if the device and the host pointer are the same |
203 | * |
204 | * \return true if they are the same |
205 | * |
206 | */ |
207 | static bool isDeviceHostSame() |
208 | { |
209 | return true; |
210 | } |
211 | }; |
212 | |
213 | /*! \brief given an alignment and an alignment it return the smallest number numiple of the alignment |
214 | * such that the value returned is bigger ot equal that the number given |
215 | * |
216 | * alignment 8 number 2 it return 8 |
217 | * alignment 8 number 9 it return 16 |
218 | * |
219 | * \param al alignment |
220 | * \param number |
221 | * |
222 | */ |
223 | inline size_t align_number(size_t al, size_t number) |
224 | { |
225 | return number + ((number % al) != 0)*(al - number % al); |
226 | } |
227 | |
228 | /*! \brief function to align a pointer equivalent to std::align |
229 | * |
230 | * function to align a pointer equivalent to std::align |
231 | * |
232 | */ |
233 | |
234 | inline void *align( std::size_t alignment, std::size_t size, |
235 | void *&ptr, std::size_t &space ) { |
236 | std::uintptr_t pn = reinterpret_cast< std::uintptr_t >( ptr ); |
237 | std::uintptr_t aligned = ( pn + alignment - 1 ) & - alignment; |
238 | std::size_t padding = aligned - pn; |
239 | if ( space < size + padding ) return nullptr; |
240 | space -= padding; |
241 | return ptr = reinterpret_cast< void * >( aligned ); |
242 | } |
243 | |
244 | #endif |
245 | |