12 #include <ChimeraTK/cppext/finally.hpp>
20 template<
typename UserType>
24 size_t numberOfWords,
size_t wordOffsetInRegister,
AccessModeFlags flags)
33 _dev = boost::dynamic_pointer_cast<LogicalNameMappingBackend>(dev);
38 if(info.targetType != LNMBackendRegisterInfo::TargetType::BIT) {
42 if(wordOffsetInRegister != 0) {
45 if(numberOfWords > 1) {
52 std::string devName = info.deviceName;
53 boost::shared_ptr<DeviceBackend> targetDevice;
54 if(devName !=
"this") {
55 targetDevice =
_dev->_devices[devName];
61 std::unique_lock<std::mutex> l{
_dev->sharedAccessorMap_mutex};
62 auto& map = boost::fusion::at_key<uint64_t>(
_dev->sharedAccessorMap.table);
68 auto it = map.find(key);
72 if(it == map.end() || (
_accessor = map[key].accessor.lock()) ==
nullptr) {
73 _accessor = targetDevice->getRegisterAccessor<uint64_t>(key.second, numberOfWords, wordOffsetInRegister, {});
74 if(
_accessor->getNumberOfSamples() != 1) {
79 lock = std::unique_lock<std::recursive_mutex>(map[key].mutex, std::defer_lock);
90 assert(
lock.owns_lock());
95 assert(
lock.owns_lock());
105 auto unlock = cppext::finally([
this] { this->
lock.unlock(); });
107 if(!hasNewData)
return;
114 this->_versionNumber = {};
115 this->_dataValidity =
_accessor->dataValidity();
129 _accessor->setDataValidity(this->_dataValidity);
134 auto unlock = cppext::finally([
this] { this->
lock.unlock(); });
138 [[nodiscard]]
bool mayReplaceOther(
const boost::shared_ptr<TransferElement const>& other)
const override {
139 auto rhsCasted = boost::dynamic_pointer_cast<const LNMBackendBitAccessor<UserType>>(other);
140 if(!rhsCasted)
return false;
142 if(
_dev != rhsCasted->_dev)
return false;
147 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
152 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
157 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
162 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
163 this->_exceptionBackend = exceptionBackend;
164 _accessor->setExceptionBackend(exceptionBackend);
169 boost::shared_ptr<NDRegisterAccessor<uint64_t>>
_accessor;
173 std::unique_lock<std::recursive_mutex>
lock;
184 boost::shared_ptr<LogicalNameMappingBackend>
_dev;
195 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
196 return _accessor->getHardwareAccessingElements();
200 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
201 auto result =
_accessor->getInternalElements();
207 std::lock_guard<std::recursive_mutex> guard(*
lock.mutex());
208 auto casted = boost::dynamic_pointer_cast<NDRegisterAccessor<uint64_t>>(newElement);
209 if(casted &&
_accessor->mayReplaceOther(newElement)) {
210 _accessor = detail::createCopyDecorator<uint64_t>(casted);
213 _accessor->replaceTransferElement(newElement);
215 _accessor->setExceptionBackend(this->_exceptionBackend);