Browse Source

ensure safety for waitoncomplete when allocation failure is encountered

master
Constantin Fürst 10 months ago
parent
commit
a338ea7906
  1. 19
      offloading-cacher/cache.hpp

19
offloading-cacher/cache.hpp

@ -149,11 +149,13 @@ namespace dsacache {
size_t GetSize() const { return size_; } size_t GetSize() const { return size_; }
uint8_t* GetSource() const { return src_; } uint8_t* GetSource() const { return src_; }
int32_t GetRefCount() const { return active_->load(); } int32_t GetRefCount() const { return active_->load(); }
void SetCacheToSource() { cache_->store(src_); delete_ = false; }
void SetInvalidHandlersAndCacheToSource();
void SetTaskHandlersAndCache(uint8_t* cache, std::vector<dml_handler>* handlers); void SetTaskHandlersAndCache(uint8_t* cache, std::vector<dml_handler>* handlers);
// initializes the class after which it is thread safe // initializes the class after which it is thread safe
// but may only be destroyed safely after setting handlers // but may only be destroyed safely after setting handlers
// afterwards either SetTaskHandlersAndCache or
// SetCacheToSource must be called to prevent deadlocks
void Init(std::vector<dml_handler>* invalid_handlers); void Init(std::vector<dml_handler>* invalid_handlers);
friend Cache; friend Cache;
@ -291,6 +293,9 @@ namespace dsacache {
// source node for further usage // source node for further usage
// output may depend on the calling threads node assignment // output may depend on the calling threads node assignment
// as this is set as the "optimal placement" node // 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; 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 // checks whether the cache contains an entry for
@ -409,7 +414,7 @@ inline std::unique_ptr<dsacache::CacheData> dsacache::Cache::Access(uint8_t* dat
// data source location // data source location
if (CheckFlag(flags, FLAG_ACCESS_WEAK)) { if (CheckFlag(flags, FLAG_ACCESS_WEAK)) {
task->SetCacheToSource();
task->SetInvalidHandlersAndCacheToSource();
return std::move(task); 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()); uint8_t* dst = memory_allocate_function_(dst_node, task->GetSize());
if (dst == nullptr) { if (dst == nullptr) {
// allocation failure encountered, therefore submission is aborted
// which necessitates making the CacheData instance safe for usage
task->SetInvalidHandlersAndCacheToSource();
return; return;
} }
@ -794,6 +802,13 @@ void dsacache::CacheData::SetTaskHandlersAndCache(uint8_t* cache, std::vector<dm
handlers_->notify_one(); handlers_->notify_one();
} }
void dsacache::CacheData::SetInvalidHandlersAndCacheToSource() {
cache_->store(src_);
delete_ = false;
handlers_->store(invalid_handlers_);
handlers_->notify_all();
}
void dsacache::CacheData::Init(std::vector<dml_handler>* invalid_handlers) { void dsacache::CacheData::Init(std::vector<dml_handler>* invalid_handlers) {
cache_->store(nullptr); cache_->store(nullptr);
delete_ = true; delete_ = true;

Loading…
Cancel
Save