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
17typedef 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 */
39class 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
60public:
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 */
223inline 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
234inline 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