1 // Copyright (C) 2018 Intel Corporation
3 // SPDX-License-Identifier: Apache-2.0
6 #include "memory/memory_accessor.hpp"
10 #include "util/zip_range.hpp"
11 #include "util/assert.hpp"
16 MemoryAccessor::MemoryAccessor()
20 MemoryAccessor::~MemoryAccessor()
22 if (!m_activeHandles.empty())
24 onError("Data wasn't committed");
28 ASSERT(m_activeHandles.empty() && "There are an opened handles");
30 for (auto listener : m_accessListeners)
32 listener->memoryDescriptorDestroyedImpl();
36 void MemoryAccessor::addListener(IMemoryAccessListener* listener)
38 ASSERT(nullptr != listener);
39 if (!m_activeHandles.empty())
41 onError("Data wasn't committed");
43 ASSERT(m_accessListeners.end() == std::find(m_accessListeners.begin(),
44 m_accessListeners.end(),
46 m_accessListeners.push_back(listener);
49 void MemoryAccessor::removeListener(IMemoryAccessListener* listener)
51 ASSERT(nullptr != listener);
52 if (!m_activeHandles.empty())
54 onError("Data wasn't committed");
55 abandonListenerHandles(listener);
57 auto it = std::find(m_accessListeners.begin(),
58 m_accessListeners.end(),
60 ASSERT(m_accessListeners.end() != it);
61 *it = m_accessListeners.back();
62 m_accessListeners.pop_back();
65 MemoryAccessor::AccessHandle MemoryAccessor::access(const MemoryDescriptor& desc,
66 const memory::DynMdSpan& span,
67 MemoryAccessType accessType)
69 ASSERT(nullptr != m_memory);
70 return m_activeHandles.emplace(m_activeHandles.end(), this, desc, span, accessType);
73 void MemoryAccessor::commit(MemoryAccessor::AccessHandle handle)
75 ASSERT(nullptr != m_memory);
76 ASSERT(m_activeHandles.end() != handle);
77 m_activeHandles.erase(handle);
80 void MemoryAccessor::setNewView(const memory::DynMdView<void>& mem)
82 if (!m_activeHandles.empty())
84 onError("Data wasn't committed");
87 for (auto& listener: m_accessListeners)
89 listener->memoryViewChangedImpl(m_memory, mem);
94 void MemoryAccessor::abandonListenerHandles(IMemoryAccessListener* listener)
96 ASSERT(nullptr != listener);
98 for (auto& h: m_activeHandles)
104 void MemoryAccessor::abandonAllHandles()
106 for (auto& h: m_activeHandles)
110 m_activeHandles.clear();
113 void MemoryAccessor::onError(const char* str)
115 ASSERT(nullptr != str);
118 m_errorListener(str);
122 MemoryAccessor::SavedHandles::SavedHandles(MemoryAccessor* parent,
123 const MemoryDescriptor& desc,
124 const memory::DynMdSpan& span,
125 MemoryAccessType accessType)
127 ASSERT(nullptr != parent);
128 using namespace util;
130 // TODO: exception safety
131 for (auto&& i: indexed(parent->m_accessListeners))
133 auto listener = value(i);
136 handle = listener->access(desc, span, accessType);
140 handles.emplace_back(listener->access(desc, span, accessType));
145 MemoryAccessor::SavedHandles::~SavedHandles()
150 void MemoryAccessor::SavedHandles::abandon(IMemoryAccessListener* listener)
152 ASSERT(nullptr != listener);
154 if (listener == handle.get_deleter().listener)
158 for (auto& h: handles)
160 if (listener == h.get_deleter().listener)
167 void MemoryAccessor::SavedHandles::abandon()
170 for (auto& h: handles)