Correct handling of failed lazy_ptr constructors.

Contructor function must not be attempted twice even if the construction
attempt returns nullptr.

Change-Id: I75353e5e511769a96e4332f7f60887f6559c1cd5
Этот коммит содержится в:
Sean Keely
2020-05-06 23:02:44 -05:00
родитель bccb25fc33
Коммит 2fbacccaed
2 изменённых файлов: 17 добавлений и 7 удалений
+2 -2
Просмотреть файл
@@ -137,7 +137,7 @@ GpuAgent::GpuAgent(HSAuint32 node, const HsaNodeProperties& node_props)
GpuAgent::~GpuAgent() {
for (auto& blit : blits_) {
if (blit.created()) {
if (!blit.empty()) {
hsa_status_t status = blit->Destroy(*this);
assert(status == HSA_STATUS_SUCCESS);
}
@@ -680,7 +680,7 @@ hsa_status_t GpuAgent::DmaFill(void* ptr, uint32_t value, size_t count) {
hsa_status_t GpuAgent::EnableDmaProfiling(bool enable) {
for (auto& blit : blits_) {
if (blit.created()) {
if (!blit.empty()) {
const hsa_status_t stat = blit->EnableProfiling(enable);
if (stat != HSA_STATUS_SUCCESS) {
return stat;
+15 -5
Просмотреть файл
@@ -87,6 +87,7 @@ template <typename T> class lazy_ptr {
const std::unique_ptr<T>& operator->() const {
make(true);
assert(obj != nullptr && "Null dereference through lazy_ptr.");
return obj;
}
@@ -107,7 +108,17 @@ template <typename T> class lazy_ptr {
void touch() const { make(false); }
// Tells if the lazy object has been constructed or not.
bool created() const { return obj != nullptr; }
// Construction may fail silently (return nullptr).
bool created() const {
std::atomic_thread_fence(std::memory_order_acquire);
return func == nullptr;
}
// Tells if the lazy object exists or not.
bool empty() const {
std::atomic_thread_fence(std::memory_order_acquire);
return obj == nullptr;
}
private:
mutable std::unique_ptr<T> obj;
@@ -122,16 +133,15 @@ template <typename T> class lazy_ptr {
return;
}
MAKE_SCOPE_GUARD([&]() { lock.Release(); });
if (obj != nullptr) return;
if (func == nullptr) return;
T* ptr = func();
std::atomic_thread_fence(std::memory_order_release);
obj.reset(ptr);
std::atomic_thread_fence(std::memory_order_release);
func = nullptr;
}
__forceinline void make(bool block) const {
std::atomic_thread_fence(std::memory_order_acquire);
if (obj == nullptr) {
if (!created()) {
make_body(block);
}
}