|
@ -392,7 +392,6 @@ 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)) { |
|
|
std::cerr << "[!] CacheAccess with WEAK set encountered miss!" << std::endl; |
|
|
|
|
|
task->SetCacheToSource(); |
|
|
task->SetCacheToSource(); |
|
|
return std::move(task); |
|
|
return std::move(task); |
|
|
} |
|
|
} |
|
@ -740,8 +739,12 @@ inline void dsacache::CacheData::WaitOnCompletion() { |
|
|
// exchange the global handlers pointer with nullptr to have a local
|
|
|
// exchange the global handlers pointer with nullptr to have a local
|
|
|
// copy - this signals that this thread is the sole owner and therefore
|
|
|
// copy - this signals that this thread is the sole owner and therefore
|
|
|
// responsible for waiting for them. we can not set to nullptr here but
|
|
|
// responsible for waiting for them. we can not set to nullptr here but
|
|
|
// set to maximum of 64-bit in order to prevent deadlocks from the above
|
|
|
|
|
|
// waiting construct
|
|
|
|
|
|
|
|
|
// set to secondary invalid value in order to prevent deadlocks from
|
|
|
|
|
|
// the above waiting construct, where threads may miss the short period
|
|
|
|
|
|
// in which the handlers are not nullptr. we could use double width cas
|
|
|
|
|
|
// which however is more expensive and therefore introduce the second
|
|
|
|
|
|
// invalid state to solve the aba occurring here
|
|
|
|
|
|
// see https://en.wikipedia.org/wiki/ABA_problem for more info
|
|
|
|
|
|
|
|
|
std::vector<dml_handler>* local_handlers = handlers_->exchange(invalid_handlers_); |
|
|
std::vector<dml_handler>* local_handlers = handlers_->exchange(invalid_handlers_); |
|
|
|
|
|
|
|
|