Publishing 2020.1 content
[platform/upstream/dldt.git] / inference-engine / include / ie_locked_memory.hpp
1 // Copyright (C) 2018-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 /**
6  * @brief A header file for generic LockedMemory<> and different variations of locks
7  *
8  * @file ie_locked_memory.hpp
9  */
10 #pragma once
11
12 #include <iostream>
13 #include <utility>
14
15 #include "ie_allocator.hpp"
16
17 namespace InferenceEngine {
18 namespace details {
19 /**
20  * @brief This class is a LockedMemory concept for hardware memory
21  */
22 template <class T>
23 class LockedMemoryBase {
24     IAllocator* _allocator = nullptr;
25     void* _handle = nullptr;
26     mutable T* _locked = nullptr;
27     LockOp _lockFlag = LOCK_FOR_WRITE;
28
29 protected:
30     /**
31      * @brief An offset size
32      *
33      * The default value is 0.
34      */
35     size_t _offset = 0;
36
37 public:
38     /**
39      * @brief A constructor
40      *
41      * @param ptr Pointer to an IAllocator object
42      * @param handle Handle provided by allocator->Alloc()
43      * @param lockFlag Read/Write type of mapping
44      * @param offsetInBytes Offset in originally locked region
45      */
46     LockedMemoryBase(IAllocator* ptr, void* handle, LockOp lockFlag, size_t offsetInBytes)
47         : _allocator(ptr), _handle(handle), _lockFlag(lockFlag), _offset(offsetInBytes) {}
48
49     /**
50      * @brief A copy constructor
51      *
52      * @param that An rvalue reference for the other LockedMemoryBase instance
53      */
54     LockedMemoryBase(LockedMemoryBase&& that)
55         : _allocator(that._allocator), _handle(that._handle), _lockFlag(that._lockFlag), _offset(that._offset) {
56         that._locked = nullptr;
57     }
58
59     /**
60      * @brief A virtual destructor
61      */
62     virtual ~LockedMemoryBase() {
63         if (_locked != nullptr) {
64             _allocator->unlock(_handle);
65         }
66     }
67
68 protected:
69     /**
70      * @brief Compares referenced values
71      *
72      * @param pointer Pointer to the object to compare with
73      * @return True if all handlers are nullptr or referenced values are equal, false otherwise
74      */
75     bool isEqualTo(const T* pointer) const {
76         if (pointer == nullptr && (_allocator == nullptr || _handle == nullptr)) {
77             return true;
78         }
79         return dereference() == pointer;
80     }
81
82     /**
83      * @brief Gets the locked object.
84      *
85      * Locks the handler and casts memory to the object of the given template type.
86      *
87      * @return The pointer to the locked object, nullptr otherwise
88      */
89     virtual T* dereference() const {
90         if (_locked != nullptr) return _locked;
91
92         if (_allocator == nullptr) {
93             return nullptr;
94         }
95
96         if (_handle == nullptr) {
97             return nullptr;
98         }
99
100         uint8_t* pBytes = reinterpret_cast<uint8_t*>(_allocator->lock(_handle, _lockFlag));
101
102         return _locked = reinterpret_cast<T*>(pBytes + _offset);
103     }
104 };
105 }  // namespace details
106
107 /**
108  * @brief This class represents locked memory for read/write memory
109  */
110 template <class T>
111 class LockedMemory : public details::LockedMemoryBase<T> {
112     using base = details::LockedMemoryBase<T>;
113
114 public:
115     /**
116      * @brief A constructor
117      *
118      * @param ptr Pointer to IAllocator object
119      * @param handle Handle provided by allocator
120      * @param offsetInBytes Offset in originally locked region
121      */
122     LockedMemory(IAllocator* ptr, void* handle, size_t offsetInBytes = 0)
123         : base(ptr, handle, LOCK_FOR_WRITE, offsetInBytes) {}
124
125     /**
126      * @brief A default copy constructor, accepting rvalue
127      */
128     LockedMemory(LockedMemory<T>&&) = default;
129
130     /**
131      * @brief A default copy constructor that accepts rvalue
132      *
133      * Also sets the offset value for the new memory object
134      *
135      * @param that Rvalue reference for the other LockedMemoryBase instance
136      * @param offset Offset value
137      */
138     LockedMemory(LockedMemory<T>&& that, size_t offset): base(std::move(that)) {
139         base::_offset = offset;
140     }
141
142     /**
143      * @brief A disabled copy constructor for lvalue
144      */
145     LockedMemory(const LockedMemory<T>&) = delete;
146
147     /**
148      * @brief Gets a pointer to the stored object
149      *
150      * Dereferences from the base class.
151      *
152      * @return The pointer to the object of the given template type
153      */
154     operator T*() {
155         return base::dereference();
156     }
157
158     /**
159      * @brief Gets the const pointer to the stored object
160      *
161      * Dereferences from the base class.
162      * @return The const pointer object of the given template type.
163      */
164     operator const T*() const {
165         return base::dereference();
166     }
167
168     /**
169      * @brief Compares stored object with the given one
170      *
171      * @return true if objects are equal, false otherwise
172      */
173     bool operator==(const T* pointer) const {
174         // special case with nullptr
175         return base::isEqualTo(pointer);
176     }
177
178     /**
179      * @brief Compares the object with the one stored in the memory.
180      *
181      * @return true if objects are equal, false otherwise
182      */
183     friend bool operator==(const T* pointer, const LockedMemory<T>& lm) {
184         return lm.operator==(pointer);
185     }
186
187     /**
188      * @brief Casts stored object to any provided type.
189      *
190      * Uses reinterpret_cast.
191      *
192      * @tparam S Type to be casted to
193      * @return Casted to the given type object
194      */
195     template <class S, typename = std::enable_if<std::is_pointer<S>::value>>
196     S as() {
197         return reinterpret_cast<S>(base::dereference());
198     }
199
200     /**
201      * @brief Casts stored object to any provided type.
202      *
203      * Uses reinterpret_cast.
204      *
205      * @tparam S Type to be casted to
206      * @return Casted to the given type const object
207      */
208     template <class S, typename = std::enable_if<std::is_pointer<S>::value>>
209     const S as() const {
210         return reinterpret_cast<S>(base::dereference());
211     }
212 };
213
214 /**
215  * @brief This class is for <void*> data and allows casting to any pointers
216  */
217 template <>
218 class LockedMemory<void> : public details::LockedMemoryBase<void> {
219     using base = details::LockedMemoryBase<void>;
220
221 public:
222     /**
223      * @brief A constructor
224      *
225      * @param ptr Pointer to IAllocator object
226      * @param handle Handle provided by allocator
227      * @param offsetInBytes Offset in originally locked region
228      */
229     LockedMemory(IAllocator* ptr, void* handle, size_t offsetInBytes)
230         : base(ptr, handle, LOCK_FOR_WRITE, offsetInBytes) {}
231
232     /**
233      * @brief A default copy constructor that accepts rvalue
234      */
235     LockedMemory(LockedMemory<void>&&) = default;
236
237     /**
238      * @brief A default copy constructor that accepts rvalue
239      *
240      * Also sets the offset value for the new memory object
241      *
242      * @param that Rvalue reference for the other LockedMemoryBase instance
243      * @param offset Offset value
244      */
245     LockedMemory(LockedMemory<void>&& that, size_t offset): base(std::move(that)) {
246         base::_offset = offset;
247     }
248
249     /**
250      * @brief A disabled copy constructor for lvalue
251      */
252     LockedMemory(const LockedMemory<void>&) = delete;
253
254     /**
255      * @brief Gets the pointer to the stored object of the given template type
256      *
257      * Dereferences from the base class.
258      *
259      * @tparam S Type to be casted to
260      * @return The pointer to the object of the given template type
261      */
262     template <class S>
263     operator S*() {
264         return reinterpret_cast<S*>(base::dereference());
265     }
266
267     /**
268      * @brief Compares stored object with the given one
269      *
270      * @return true if objects are equal, false otherwise
271      */
272     bool operator==(const void* pointer) const {
273         // special case with nullptr
274         return base::isEqualTo(pointer);
275     }
276
277     /**
278      * @brief Compares the object with the one stored in the memory
279      *
280      * @return true if objects are equal, false otherwise
281      */
282     friend bool operator==(const void* pointer, const LockedMemory<void>& lm) {
283         return lm.operator==(pointer);
284     }
285
286     /**
287      * @brief Casts stored object to any given type
288      *
289      * Uses reinterpret_cast.
290      *
291      * @tparam S Type to be casted to
292      * @return Casted to the given type object
293      */
294     template <class S, typename = std::enable_if<std::is_pointer<S>::value>>
295     S as() {
296         return reinterpret_cast<S>(dereference());
297     }
298
299     /**
300      * @brief Casts stored object to any given type
301      *
302      * Uses reinterpret_cast.
303      *
304      * @tparam S Type to be casted to
305      * @return Casted to the given type const object
306      */
307     template <class S, typename = std::enable_if<std::is_pointer<S>::value>>
308     const S as() const {
309         return reinterpret_cast<S>(dereference());
310     }
311 };
312
313 /**
314  * @brief This class is for read-only segments
315  */
316 template <class T>
317 class LockedMemory<const T> : public details::LockedMemoryBase<T> {
318     using base = details::LockedMemoryBase<T>;
319
320 public:
321     /**
322      * @brief A constructor
323      *
324      * @param ptr Pointer to IAllocator object
325      * @param handle Handle provided by allocator
326      * @param offsetInBytes Offset in originally locked region
327      */
328     LockedMemory(IAllocator* ptr, void* handle, size_t offset): base(ptr, handle, LOCK_FOR_READ, offset) {}
329
330     /**
331      * @brief A default copy constructor that accepts rvalue
332      */
333     LockedMemory(LockedMemory<const T>&&) = default;
334
335     /**
336      * @brief A default copy constructor that accepts rvalue.
337      *
338      * Also sets the offset value for the new memory object
339      *
340      * @param that Rvalue reference for the other LockedMemoryBase instance
341      * @param offset Offset value
342      */
343     LockedMemory(LockedMemory<const T>&& that, size_t offset): base(std::move(that)) {
344         base::_offset = offset;
345     }
346
347     /**
348      * @brief A disabled copy constructor for lvalue
349      */
350     LockedMemory(const LockedMemory<const T>&) = delete;
351
352     /**
353      * @brief Gets the const pointer to the stored object
354      *
355      * Dereferences from the base class.
356      *
357      * @return The pointer to the object.
358      */
359     operator const T*() const {
360         return base::dereference();
361     }
362
363     /**
364      * @brief Compares stored object with the given one
365      *
366      * @return true if objects are equal, false otherwise
367      */
368     bool operator==(const T* pointer) const {
369         // special case with nullptr
370         return base::isEqualTo(pointer);
371     }
372
373     /**
374      * @brief Compares the object with the one stored in the memory
375      *
376      * @return true if objects are equal, false otherwise
377      */
378     friend bool operator==(const T* pointer, const LockedMemory<const T>& lm) {
379         return lm.operator==(pointer);
380     }
381
382     /**
383      * @brief Casts stored object to any given type.
384      *
385      * Uses reinterpret_cast.
386      *
387      * @tparam S Type to be casted to
388      * @return Casted to the given type object
389      */
390     template <class S, typename = std::enable_if<std::is_pointer<S>::value && std::is_const<S>::value>>
391     S as() const {
392         return reinterpret_cast<S>(base::dereference());
393     }
394 };
395 }  // namespace InferenceEngine