diff --git a/offloading-cacher/cache.hpp b/offloading-cacher/cache.hpp index 5ac1b42..8b1253e 100755 --- a/offloading-cacher/cache.hpp +++ b/offloading-cacher/cache.hpp @@ -149,11 +149,13 @@ namespace dsacache { size_t GetSize() const { return size_; } uint8_t* GetSource() const { return src_; } int32_t GetRefCount() const { return active_->load(); } - void SetCacheToSource() { cache_->store(src_); delete_ = false; } + void SetInvalidHandlersAndCacheToSource(); void SetTaskHandlersAndCache(uint8_t* cache, std::vector* handlers); // initializes the class after which it is thread safe // but may only be destroyed safely after setting handlers + // afterwards either SetTaskHandlersAndCache or + // SetCacheToSource must be called to prevent deadlocks void Init(std::vector* invalid_handlers); friend Cache; @@ -291,6 +293,9 @@ namespace dsacache { // source node for further usage // output may depend on the calling threads node assignment // as this is set as the "optimal placement" node + // TODO: it would be better to not handle any decisions regarding nodes in the cache + // TODO: and leave this entirely to the user, however, this idea came to me 3 days before + // TODO: submission date and there are more important things to do void GetCacheNode(uint8_t* src, const size_t size, int* OUT_DST_NODE, int* OUT_SRC_NODE) const; // checks whether the cache contains an entry for @@ -409,7 +414,7 @@ inline std::unique_ptr dsacache::Cache::Access(uint8_t* dat // data source location if (CheckFlag(flags, FLAG_ACCESS_WEAK)) { - task->SetCacheToSource(); + task->SetInvalidHandlersAndCacheToSource(); return std::move(task); } @@ -454,6 +459,9 @@ inline void dsacache::Cache::SubmitTask(CacheData* task, const int dst_node, con uint8_t* dst = memory_allocate_function_(dst_node, task->GetSize()); if (dst == nullptr) { + // allocation failure encountered, therefore submission is aborted + // which necessitates making the CacheData instance safe for usage + task->SetInvalidHandlersAndCacheToSource(); return; } @@ -794,6 +802,13 @@ void dsacache::CacheData::SetTaskHandlersAndCache(uint8_t* cache, std::vectornotify_one(); } +void dsacache::CacheData::SetInvalidHandlersAndCacheToSource() { + cache_->store(src_); + delete_ = false; + handlers_->store(invalid_handlers_); + handlers_->notify_all(); +} + void dsacache::CacheData::Init(std::vector* invalid_handlers) { cache_->store(nullptr); delete_ = true;