Publishing R3
[platform/upstream/dldt.git] / inference-engine / thirdparty / ade / ade / source / memory_accessor.cpp
1 // Copyright (C) 2018 Intel Corporation
2 //
3 // SPDX-License-Identifier: Apache-2.0
4 //
5
6 #include "memory/memory_accessor.hpp"
7
8 #include <algorithm>
9
10 #include "util/zip_range.hpp"
11 #include "util/assert.hpp"
12
13 namespace ade
14 {
15
16 MemoryAccessor::MemoryAccessor()
17 {
18 }
19
20 MemoryAccessor::~MemoryAccessor()
21 {
22     if (!m_activeHandles.empty())
23     {
24         onError("Data wasn't committed");
25         abandonAllHandles();
26     }
27
28     ASSERT(m_activeHandles.empty() && "There are an opened handles");
29
30     for (auto listener : m_accessListeners)
31     {
32         listener->memoryDescriptorDestroyedImpl();
33     }
34 }
35
36 void MemoryAccessor::addListener(IMemoryAccessListener* listener)
37 {
38     ASSERT(nullptr != listener);
39     if (!m_activeHandles.empty())
40     {
41         onError("Data wasn't committed");
42     }
43     ASSERT(m_accessListeners.end() == std::find(m_accessListeners.begin(),
44                                                 m_accessListeners.end(),
45                                                 listener));
46     m_accessListeners.push_back(listener);
47 }
48
49 void MemoryAccessor::removeListener(IMemoryAccessListener* listener)
50 {
51     ASSERT(nullptr != listener);
52     if (!m_activeHandles.empty())
53     {
54         onError("Data wasn't committed");
55         abandonListenerHandles(listener);
56     }
57     auto it = std::find(m_accessListeners.begin(),
58                         m_accessListeners.end(),
59                         listener);
60     ASSERT(m_accessListeners.end() != it);
61     *it = m_accessListeners.back();
62     m_accessListeners.pop_back();
63 }
64
65 MemoryAccessor::AccessHandle MemoryAccessor::access(const MemoryDescriptor& desc,
66                                                     const memory::DynMdSpan& span,
67                                                     MemoryAccessType accessType)
68 {
69     ASSERT(nullptr != m_memory);
70     return m_activeHandles.emplace(m_activeHandles.end(), this, desc, span, accessType);
71 }
72
73 void MemoryAccessor::commit(MemoryAccessor::AccessHandle handle)
74 {
75     ASSERT(nullptr != m_memory);
76     ASSERT(m_activeHandles.end() != handle);
77     m_activeHandles.erase(handle);
78 }
79
80 void MemoryAccessor::setNewView(const memory::DynMdView<void>& mem)
81 {
82     if (!m_activeHandles.empty())
83     {
84         onError("Data wasn't committed");
85         abandonAllHandles();
86     }
87     for (auto& listener: m_accessListeners)
88     {
89         listener->memoryViewChangedImpl(m_memory, mem);
90     }
91     m_memory = mem;
92 }
93
94 void MemoryAccessor::abandonListenerHandles(IMemoryAccessListener* listener)
95 {
96     ASSERT(nullptr != listener);
97
98     for (auto& h: m_activeHandles)
99     {
100         h.abandon(listener);
101     }
102 }
103
104 void MemoryAccessor::abandonAllHandles()
105 {
106     for (auto& h: m_activeHandles)
107     {
108         h.abandon();
109     }
110     m_activeHandles.clear();
111 }
112
113 void MemoryAccessor::onError(const char* str)
114 {
115     ASSERT(nullptr != str);
116     if (m_errorListener)
117     {
118         m_errorListener(str);
119     }
120 }
121
122 MemoryAccessor::SavedHandles::SavedHandles(MemoryAccessor* parent,
123                                            const MemoryDescriptor& desc,
124                                            const memory::DynMdSpan& span,
125                                            MemoryAccessType accessType)
126 {
127     ASSERT(nullptr != parent);
128     using namespace util;
129
130     // TODO: exception safety
131     for (auto&& i: indexed(parent->m_accessListeners))
132     {
133         auto listener = value(i);
134         if (0 == index(i))
135         {
136             handle = listener->access(desc, span, accessType);
137         }
138         else
139         {
140             handles.emplace_back(listener->access(desc, span, accessType));
141         }
142     }
143 }
144
145 MemoryAccessor::SavedHandles::~SavedHandles()
146 {
147
148 }
149
150 void MemoryAccessor::SavedHandles::abandon(IMemoryAccessListener* listener)
151 {
152     ASSERT(nullptr != listener);
153
154     if (listener == handle.get_deleter().listener)
155     {
156         handle.release();
157     }
158     for (auto& h: handles)
159     {
160         if (listener == h.get_deleter().listener)
161         {
162             h.release();
163         }
164     }
165 }
166
167 void MemoryAccessor::SavedHandles::abandon()
168 {
169     handle.release();
170     for (auto& h: handles)
171     {
172         h.release();
173     }
174 }
175 }