diff --git a/openmp/libomptarget/include/ExclusiveAccess.h b/openmp/libomptarget/include/ExclusiveAccess.h new file mode 100644 --- /dev/null +++ b/openmp/libomptarget/include/ExclusiveAccess.h @@ -0,0 +1,87 @@ +//===---- ExclusiveAccess.h - Helper for exclusive access data structures -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#ifndef OMPTARGET_EXCLUSIVE_ACCESS +#define OMPTARGET_EXCLUSIVE_ACCESS + +#include +#include +#include + +/// Forward declaration. +template struct Accessor; + +/// A proteted object is a simple wrapper to allocate an object of type \p Ty +/// together with a mutext that guards accesses to the object. The only way to +/// access the object is through the "exclusive accessor" which will lock the +/// mutex accordingly. +template struct ProtectedObj { + using AccessorTy = Accessor; + AccessorTy &&getExclusiveAccessor(bool DoNotGetAccess = false); + +private: + Ty Obj; + std::mutex Mtx; + friend struct Accessor; +}; + +/// Helper to provide trnasparent exclusive access to protected objects. +template struct Accessor { + /// Constructor to get exclusive access by locking the mutext protecting the + /// underlying object. \p DoNotGetAccess allows to create an accessor that is + /// not owning anything based on a boolean condition. + Accessor(ProtectedObj &PO, bool DoNotGetAccess = false) + : Ptr(DoNotGetAccess ? nullptr : &PO) { + lock(); + } + + /// Constructor to get exclusive access by taking it from \p Other. + Accessor(Accessor &&Other) : Ptr(Other.Ptr) { Other.Ptr = nullptr; } + + Accessor(Accessor &Other) = delete; + + /// If the object is still owned when the lifetime ends we give up access. + ~Accessor() { unlock(); } + + /// Give up access to the underlying object, virtually "destroying" the + /// accessor even if the object is still life. + void destroy() { + unlock(); + Ptr = nullptr; + } + + /// Provide transparent access to the underlying object. + Ty &operator*() { return Ptr->Obj; } + Ty *operator->() { return &Ptr->Obj; } + +private: + /// Lock the underlyign object if there is one. + void lock() { + if (Ptr) + Ptr->Mtx.lock(); + } + + /// Unlock the underlyign object if there is one. + void unlock() { + if (Ptr) + Ptr->Mtx.unlock(); + } + + /// Pointer to the underlying object or null if the accessor lost access, + /// e.g., after a destroy call. + ProtectedObj *Ptr; +}; + +template +Accessor &&ProtectedObj::getExclusiveAccessor(bool DoNotGetAccess) { + return std::move(Accessor(*this, DoNotGetAccess)); +} + +#endif diff --git a/openmp/libomptarget/include/device.h b/openmp/libomptarget/include/device.h --- a/openmp/libomptarget/include/device.h +++ b/openmp/libomptarget/include/device.h @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include +#include "ExclusiveAccess.h" #include "omptarget.h" #include "rtl.h" @@ -218,20 +220,32 @@ void unlock() const { States->UpdateMtx.unlock(); } }; -typedef uintptr_t HstPtrBeginTy; -inline bool operator<(const HostDataToTargetTy &lhs, const HstPtrBeginTy &rhs) { - return lhs.HstPtrBegin < rhs; +/// Wrapper around the HostDataToTargetTy to be used in the HDTT map. In +/// addition to the HDTT pointer we store the key value explicitly. This +/// allows the set to inspect (sort/search/...) this entry without an additional +/// load of HDTT. HDTT is a pointer to allow the modification of the set without +/// invalidating HDTT entries which can now be inspected at the same time. +struct HostDataToTargetMapKeyTy { + uintptr_t KeyValue; + + HostDataToTargetMapKeyTy(void *Key) : KeyValue(uintptr_t(Key)) {} + HostDataToTargetMapKeyTy(HostDataToTargetTy *HDTT) + : KeyValue(HDTT->HstPtrBegin), HDTT(HDTT) {} + HostDataToTargetTy *HDTT; +}; +inline bool operator<(const HostDataToTargetMapKeyTy &lhs, + const uintptr_t &rhs) { + return lhs.KeyValue < rhs; } -inline bool operator<(const HstPtrBeginTy &lhs, const HostDataToTargetTy &rhs) { - return lhs < rhs.HstPtrBegin; +inline bool operator<(const uintptr_t &lhs, + const HostDataToTargetMapKeyTy &rhs) { + return lhs < rhs.KeyValue; } -inline bool operator<(const HostDataToTargetTy &lhs, - const HostDataToTargetTy &rhs) { - return lhs.HstPtrBegin < rhs.HstPtrBegin; +inline bool operator<(const HostDataToTargetMapKeyTy &lhs, + const HostDataToTargetMapKeyTy &rhs) { + return lhs.KeyValue < rhs.KeyValue; } -typedef std::set> HostDataToTargetListTy; - struct LookupResult { struct { unsigned IsContained : 1; @@ -239,7 +253,8 @@ unsigned ExtendsAfter : 1; } Flags; - HostDataToTargetListTy::iterator Entry; + /// The corresponding map table entry which is stable. + HostDataToTargetTy *Entry = nullptr; LookupResult() : Flags({0, 0, 0}), Entry() {} }; @@ -254,8 +269,8 @@ unsigned IsHostPointer : 1; } Flags = {0, 0}; - /// The iterator to the corresponding map table entry - HostDataToTargetListTy::iterator MapTableEntry{}; + /// The corresponding map table entry which is stable. + HostDataToTargetTy *Entry = nullptr; /// The corresponding target pointer void *TargetPointer = nullptr; @@ -286,12 +301,24 @@ std::once_flag InitFlag; bool HasPendingGlobals; - HostDataToTargetListTy HostDataToTargetMap; + /// Host data to device map type with a wrapper key indirection that allows + /// concurrent modification of the entries without invalidating the underlying + /// entries. + using HostDataToTargetListTy = + std::set>; + + /// The HDTTMap is a protected object that can only be accessed by one thread + /// at a time. + ProtectedObj HostDataToTargetMap; + + /// The type used to access the HDTT map. + using HDTTMapAccessorTy = decltype(HostDataToTargetMap)::AccessorTy; + PendingCtorsDtorsPerLibrary PendingCtorsDtors; ShadowPtrListTy ShadowPtrMap; - std::mutex DataMapMtx, PendingGlobalsMtx, ShadowMtx; + std::mutex PendingGlobalsMtx, ShadowMtx; // NOTE: Once libomp gains full target-task support, this state should be // moved into the target task in libomp. @@ -307,7 +334,11 @@ // Return true if data can be copied to DstDevice directly bool isDataExchangable(const DeviceTy &DstDevice); - LookupResult lookupMapping(void *HstPtrBegin, int64_t Size); + /// Lookup the mapping of \p HstPtrBegin in \p HDTTMap. The accessor ensures + /// exclusive access to the HDTT map. + LookupResult lookupMapping(HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin, + int64_t Size); + /// Get the target pointer based on host pointer begin and base. If the /// mapping already exists, the target pointer will be returned directly. In /// addition, if required, the memory region pointed by \p HstPtrBegin of size @@ -324,7 +355,12 @@ bool HasFlagAlways, bool IsImplicit, bool UpdateRefCount, bool HasCloseModifier, bool HasPresentModifier, bool HasHoldModifier, AsyncInfoTy &AsyncInfo); - void *getTgtPtrBegin(void *HstPtrBegin, int64_t Size); + + /// Return the target pointer for \p HstPtrBegin in \p HDTTMap. The accessor + /// ensures exclusive access to the HDTT map. + void *getTgtPtrBegin(HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin, + int64_t Size); + TargetPointerResultTy getTgtPtrBegin(void *HstPtrBegin, int64_t Size, bool &IsLast, bool UpdateRefCount, bool UseHoldRefCount, bool &IsHostPtr, diff --git a/openmp/libomptarget/src/device.cpp b/openmp/libomptarget/src/device.cpp --- a/openmp/libomptarget/src/device.cpp +++ b/openmp/libomptarget/src/device.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -65,8 +66,8 @@ DeviceTy::DeviceTy(RTLInfoTy *RTL) : DeviceID(-1), RTL(RTL), RTLDeviceID(-1), IsInit(false), InitFlag(), - HasPendingGlobals(false), HostDataToTargetMap(), PendingCtorsDtors(), - ShadowPtrMap(), DataMapMtx(), PendingGlobalsMtx(), ShadowMtx() {} + HasPendingGlobals(false), PendingCtorsDtors(), ShadowPtrMap(), + PendingGlobalsMtx(), ShadowMtx() {} DeviceTy::~DeviceTy() { if (DeviceID == -1 || !(getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE)) @@ -77,14 +78,15 @@ } int DeviceTy::associatePtr(void *HstPtrBegin, void *TgtPtrBegin, int64_t Size) { - std::lock_guard LG(DataMapMtx); + HDTTMapAccessorTy HDTTMap = HostDataToTargetMap.getExclusiveAccessor(); // Check if entry exists - auto search = HostDataToTargetMap.find(HstPtrBeginTy{(uintptr_t)HstPtrBegin}); - if (search != HostDataToTargetMap.end()) { + auto It = HDTTMap->find(HstPtrBegin); + if (It != HDTTMap->end()) { + HostDataToTargetTy &HDTT = *It->HDTT; // Mapping already exists - bool isValid = search->HstPtrEnd == (uintptr_t)HstPtrBegin + Size && - search->TgtPtrBegin == (uintptr_t)TgtPtrBegin; + bool isValid = HDTT.HstPtrEnd == (uintptr_t)HstPtrBegin + Size && + HDTT.TgtPtrBegin == (uintptr_t)TgtPtrBegin; if (isValid) { DP("Attempt to re-associate the same device ptr+offset with the same " "host ptr, nothing to do\n"); @@ -98,15 +100,15 @@ // Mapping does not exist, allocate it with refCount=INF const HostDataToTargetTy &newEntry = - *HostDataToTargetMap - .emplace( + *HDTTMap + ->emplace(new HostDataToTargetTy( /*HstPtrBase=*/(uintptr_t)HstPtrBegin, /*HstPtrBegin=*/(uintptr_t)HstPtrBegin, /*HstPtrEnd=*/(uintptr_t)HstPtrBegin + Size, /*TgtPtrBegin=*/(uintptr_t)TgtPtrBegin, /*UseHoldRefCount=*/false, /*Name=*/nullptr, - /*IsRefCountINF=*/true) - .first; + /*IsRefCountINF=*/true)) + .first->HDTT; DP("Creating new map entry: HstBase=" DPxMOD ", HstBegin=" DPxMOD ", HstEnd=" DPxMOD ", TgtBegin=" DPxMOD ", DynRefCount=%s, " "HoldRefCount=%s\n", @@ -119,23 +121,25 @@ } int DeviceTy::disassociatePtr(void *HstPtrBegin) { - std::lock_guard LG(DataMapMtx); + HDTTMapAccessorTy HDTTMap = HostDataToTargetMap.getExclusiveAccessor(); - auto search = HostDataToTargetMap.find(HstPtrBeginTy{(uintptr_t)HstPtrBegin}); - if (search != HostDataToTargetMap.end()) { + auto It = HDTTMap->find(HstPtrBegin); + if (It != HDTTMap->end()) { + HostDataToTargetTy &HDTT = *It->HDTT; // Mapping exists - if (search->getHoldRefCount()) { + if (HDTT.getHoldRefCount()) { // This is based on OpenACC 3.1, sec 3.2.33 "acc_unmap_data", L3656-3657: // "It is an error to call acc_unmap_data if the structured reference // count for the pointer is not zero." REPORT("Trying to disassociate a pointer with a non-zero hold reference " "count\n"); - } else if (search->isDynRefCountInf()) { + } else if (HDTT.isDynRefCountInf()) { DP("Association found, removing it\n"); - void *Event = search->getEvent(); + void *Event = HDTT.getEvent(); + delete &HDTT; if (Event) destroyEvent(Event); - HostDataToTargetMap.erase(search); + HDTTMap->erase(It); return OFFLOAD_SUCCESS; } else { REPORT("Trying to disassociate a pointer which was not mapped via " @@ -149,20 +153,22 @@ return OFFLOAD_FAIL; } -LookupResult DeviceTy::lookupMapping(void *HstPtrBegin, int64_t Size) { +LookupResult DeviceTy::lookupMapping(HDTTMapAccessorTy &HDTTMap, + void *HstPtrBegin, int64_t Size) { + uintptr_t hp = (uintptr_t)HstPtrBegin; LookupResult lr; DP("Looking up mapping(HstPtrBegin=" DPxMOD ", Size=%" PRId64 ")...\n", DPxPTR(hp), Size); - if (HostDataToTargetMap.empty()) + if (HDTTMap->empty()) return lr; - auto upper = HostDataToTargetMap.upper_bound(hp); + auto upper = HDTTMap->upper_bound(hp); // check the left bin - if (upper != HostDataToTargetMap.begin()) { - lr.Entry = std::prev(upper); + if (upper != HDTTMap->begin()) { + lr.Entry = std::prev(upper)->HDTT; auto &HT = *lr.Entry; // Is it contained? lr.Flags.IsContained = hp >= HT.HstPtrBegin && hp < HT.HstPtrEnd && @@ -173,8 +179,8 @@ // check the right bin if (!(lr.Flags.IsContained || lr.Flags.ExtendsAfter) && - upper != HostDataToTargetMap.end()) { - lr.Entry = upper; + upper != HDTTMap->end()) { + lr.Entry = upper->HDTT; auto &HT = *lr.Entry; // Does it extend into an already mapped region? lr.Flags.ExtendsBefore = @@ -200,14 +206,14 @@ map_var_info_t HstPtrName, bool HasFlagTo, bool HasFlagAlways, bool IsImplicit, bool UpdateRefCount, bool HasCloseModifier, bool HasPresentModifier, bool HasHoldModifier, AsyncInfoTy &AsyncInfo) { + HDTTMapAccessorTy HDTTMap = HostDataToTargetMap.getExclusiveAccessor(); + void *TargetPointer = nullptr; bool IsHostPtr = false; bool IsNew = false; - DataMapMtx.lock(); - - LookupResult LR = lookupMapping(HstPtrBegin, Size); - auto Entry = LR.Entry; + LookupResult LR = lookupMapping(HDTTMap, HstPtrBegin, Size); + auto *Entry = LR.Entry; // Check if the pointer is contained. // If a variable is mapped to the device manually by the user - which would @@ -276,11 +282,12 @@ // If it is not contained and Size > 0, we should create a new entry for it. IsNew = true; uintptr_t Ptr = (uintptr_t)allocData(Size, HstPtrBegin); - Entry = HostDataToTargetMap - .emplace((uintptr_t)HstPtrBase, (uintptr_t)HstPtrBegin, - (uintptr_t)HstPtrBegin + Size, Ptr, HasHoldModifier, - HstPtrName) - .first; + Entry = HDTTMap + ->emplace(new HostDataToTargetTy( + (uintptr_t)HstPtrBase, (uintptr_t)HstPtrBegin, + (uintptr_t)HstPtrBegin + Size, Ptr, HasHoldModifier, + HstPtrName)) + .first->HDTT; INFO(OMP_INFOTYPE_MAPPING_CHANGED, DeviceID, "Creating new map entry with " "HstPtrBegin=" DPxMOD ", TgtPtrBegin=" DPxMOD ", Size=%ld, " @@ -298,7 +305,7 @@ // thread that could issue data movement will get the right result. std::lock_guard LG(*Entry); // Release the mapping table lock right after the entry is locked. - DataMapMtx.unlock(); + HDTTMap.destroy(); DP("Moving %" PRId64 " bytes (hst:" DPxMOD ") -> (tgt:" DPxMOD ")\n", Size, DPxPTR(HstPtrBegin), DPxPTR(TargetPointer)); @@ -313,16 +320,15 @@ } else if (Entry->recordEventIfNecessary(*this, AsyncInfo) != OFFLOAD_SUCCESS) return {{false /* IsNewEntry */, false /* IsHostPointer */}, - {} /* MapTableEntry */, + nullptr /* Entry */, nullptr /* TargetPointer */}; } else { // Release the mapping table lock directly. - DataMapMtx.unlock(); + HDTTMap.destroy(); // If not a host pointer and no present modifier, we need to wait for the // event if it exists. // Note: Entry might be nullptr because of zero length array section. - if (Entry != HostDataToTargetListTy::iterator() && !IsHostPtr && - !HasPresentModifier) { + if (Entry && !IsHostPtr && !HasPresentModifier) { std::lock_guard LG(*Entry); void *Event = Entry->getEvent(); if (Event) { @@ -332,7 +338,7 @@ // case of any data race. REPORT("Failed to wait for event " DPxMOD ".\n", DPxPTR(Event)); return {{false /* IsNewEntry */, false /* IsHostPointer */}, - {} /* MapTableEntry */, + nullptr /* Entry */, nullptr /* TargetPointer */}; } } @@ -349,12 +355,13 @@ DeviceTy::getTgtPtrBegin(void *HstPtrBegin, int64_t Size, bool &IsLast, bool UpdateRefCount, bool UseHoldRefCount, bool &IsHostPtr, bool MustContain, bool ForceDelete) { + HDTTMapAccessorTy HDTTMap = HostDataToTargetMap.getExclusiveAccessor(); + void *TargetPointer = NULL; bool IsNew = false; IsHostPtr = false; IsLast = false; - std::lock_guard LG(DataMapMtx); - LookupResult lr = lookupMapping(HstPtrBegin, Size); + LookupResult lr = lookupMapping(HDTTMap, HstPtrBegin, Size); if (lr.Flags.IsContained || (!MustContain && (lr.Flags.ExtendsBefore || lr.Flags.ExtendsAfter))) { @@ -408,10 +415,10 @@ } // Return the target pointer begin (where the data will be moved). -// Lock-free version called when loading global symbols from the fat binary. -void *DeviceTy::getTgtPtrBegin(void *HstPtrBegin, int64_t Size) { +void *DeviceTy::getTgtPtrBegin(HDTTMapAccessorTy &HDTTMap, void *HstPtrBegin, + int64_t Size) { uintptr_t hp = (uintptr_t)HstPtrBegin; - LookupResult lr = lookupMapping(HstPtrBegin, Size); + LookupResult lr = lookupMapping(HDTTMap, HstPtrBegin, Size); if (lr.Flags.IsContained || lr.Flags.ExtendsBefore || lr.Flags.ExtendsAfter) { auto &HT = *lr.Entry; uintptr_t tp = HT.TgtPtrBegin + (hp - HT.HstPtrBegin); @@ -423,10 +430,11 @@ int DeviceTy::deallocTgtPtr(void *HstPtrBegin, int64_t Size, bool HasHoldModifier) { + HDTTMapAccessorTy HDTTMap = HostDataToTargetMap.getExclusiveAccessor(); + // Check if the pointer is contained in any sub-nodes. int Ret = OFFLOAD_SUCCESS; - DataMapMtx.lock(); - LookupResult lr = lookupMapping(HstPtrBegin, Size); + LookupResult lr = lookupMapping(HDTTMap, HstPtrBegin, Size); if (lr.Flags.IsContained || lr.Flags.ExtendsBefore || lr.Flags.ExtendsAfter) { auto &HT = *lr.Entry; if (HT.decRefCount(HasHoldModifier) == 0) { @@ -440,7 +448,8 @@ (HT.HstPtrName) ? getNameFromMapping(HT.HstPtrName).c_str() : "unknown"); void *Event = lr.Entry->getEvent(); - HostDataToTargetMap.erase(lr.Entry); + HDTTMap->erase(lr.Entry); + delete lr.Entry; if (Event && destroyEvent(Event) != OFFLOAD_SUCCESS) { REPORT("Failed to destroy event " DPxMOD "\n", DPxPTR(Event)); Ret = OFFLOAD_FAIL; @@ -508,7 +517,8 @@ int32_t DeviceTy::submitData(void *TgtPtrBegin, void *HstPtrBegin, int64_t Size, AsyncInfoTy &AsyncInfo) { if (getInfoLevel() & OMP_INFOTYPE_DATA_TRANSFER) { - LookupResult LR = lookupMapping(HstPtrBegin, Size); + HDTTMapAccessorTy HDTTMap = HostDataToTargetMap.getExclusiveAccessor(); + LookupResult LR = lookupMapping(HDTTMap, HstPtrBegin, Size); auto *HT = &*LR.Entry; INFO(OMP_INFOTYPE_DATA_TRANSFER, DeviceID, @@ -530,7 +540,8 @@ int32_t DeviceTy::retrieveData(void *HstPtrBegin, void *TgtPtrBegin, int64_t Size, AsyncInfoTy &AsyncInfo) { if (getInfoLevel() & OMP_INFOTYPE_DATA_TRANSFER) { - LookupResult LR = lookupMapping(HstPtrBegin, Size); + HDTTMapAccessorTy HDTTMap = HostDataToTargetMap.getExclusiveAccessor(); + LookupResult LR = lookupMapping(HDTTMap, HstPtrBegin, Size); auto *HT = &*LR.Entry; INFO(OMP_INFOTYPE_DATA_TRANSFER, DeviceID, "Copying data from device to host, TgtPtr=" DPxMOD ", HstPtr=" DPxMOD diff --git a/openmp/libomptarget/src/omptarget.cpp b/openmp/libomptarget/src/omptarget.cpp --- a/openmp/libomptarget/src/omptarget.cpp +++ b/openmp/libomptarget/src/omptarget.cpp @@ -135,8 +135,8 @@ break; } - // process global data that needs to be mapped. - std::lock_guard LG(Device.DataMapMtx); + DeviceTy::HDTTMapAccessorTy HDTTMap = + Device.HostDataToTargetMap.getExclusiveAccessor(); __tgt_target_table *HostTable = &TransTable->HostTable; for (__tgt_offload_entry *CurrDeviceEntry = TargetTable->EntriesBegin, @@ -153,21 +153,23 @@ // therefore we must allow for multiple weak symbols to be loaded from // the fat binary. Treat these mappings as any other "regular" // mapping. Add entry to map. - if (Device.getTgtPtrBegin(CurrHostEntry->addr, CurrHostEntry->size)) + if (Device.getTgtPtrBegin(HDTTMap, CurrHostEntry->addr, + CurrHostEntry->size)) continue; + DP("Add mapping from host " DPxMOD " to device " DPxMOD " with size %zu" "\n", DPxPTR(CurrHostEntry->addr), DPxPTR(CurrDeviceEntry->addr), CurrDeviceEntry->size); - Device.HostDataToTargetMap.emplace( + HDTTMap->emplace(new HostDataToTargetTy( (uintptr_t)CurrHostEntry->addr /*HstPtrBase*/, (uintptr_t)CurrHostEntry->addr /*HstPtrBegin*/, (uintptr_t)CurrHostEntry->addr + CurrHostEntry->size /*HstPtrEnd*/, (uintptr_t)CurrDeviceEntry->addr /*TgtPtrBegin*/, false /*UseHoldRefCount*/, nullptr /*Name*/, - true /*IsRefCountINF*/); + true /*IsRefCountINF*/)); } } } @@ -572,13 +574,12 @@ // create or update shadow pointers for this entry Device.ShadowPtrMap[Pointer_HstPtrBegin] = { HstPtrBase, PointerTgtPtrBegin, ExpectedTgtPtrBase}; - Pointer_TPR.MapTableEntry->setMayContainAttachedPointers(); + Pointer_TPR.Entry->setMayContainAttachedPointers(); UpdateDevPtr = true; } if (UpdateDevPtr) { - std::lock_guard LG( - *Pointer_TPR.MapTableEntry); + std::lock_guard LG(*Pointer_TPR.Entry); Device.ShadowMtx.unlock(); DP("Update pointer (" DPxMOD ") -> [" DPxMOD "]\n", @@ -593,8 +594,8 @@ REPORT("Copying data to device failed.\n"); return OFFLOAD_FAIL; } - if (Pointer_TPR.MapTableEntry->recordEventIfNecessary( - Device, AsyncInfo) != OFFLOAD_SUCCESS) + if (Pointer_TPR.Entry->recordEventIfNecessary(Device, AsyncInfo) != + OFFLOAD_SUCCESS) return OFFLOAD_FAIL; } else Device.ShadowMtx.unlock(); @@ -634,8 +635,7 @@ // If the map entry for the object was never marked as containing attached // pointers, no need to do any checking. - if (TPR.MapTableEntry == HostDataToTargetListTy::iterator{} || - !TPR.MapTableEntry->getMayContainAttachedPointers()) + if (!TPR.Entry || !TPR.Entry->getMayContainAttachedPointers()) return; uintptr_t LB = (uintptr_t)Begin; diff --git a/openmp/libomptarget/src/private.h b/openmp/libomptarget/src/private.h --- a/openmp/libomptarget/src/private.h +++ b/openmp/libomptarget/src/private.h @@ -125,7 +125,9 @@ /// dump a table of all the host-target pointer pairs on failure static inline void dumpTargetPointerMappings(const ident_t *Loc, DeviceTy &Device) { - if (Device.HostDataToTargetMap.empty()) + DeviceTy::HDTTMapAccessorTy HDTTMap = + Device.HostDataToTargetMap.getExclusiveAccessor(); + if (HDTTMap->empty()) return; SourceInfo Kernel(Loc); @@ -135,18 +137,16 @@ INFO(OMP_INFOTYPE_ALL, Device.DeviceID, "%-18s %-18s %s %s %s %s\n", "Host Ptr", "Target Ptr", "Size (B)", "DynRefCount", "HoldRefCount", "Declaration"); - Device.DataMapMtx.lock(); - for (const auto &HostTargetMap : Device.HostDataToTargetMap) { - SourceInfo Info(HostTargetMap.HstPtrName); + for (const auto &It : *HDTTMap) { + HostDataToTargetTy &HDTT = *It.HDTT; + SourceInfo Info(HDTT.HstPtrName); INFO(OMP_INFOTYPE_ALL, Device.DeviceID, DPxMOD " " DPxMOD " %-8" PRIuPTR " %-11s %-12s %s at %s:%d:%d\n", - DPxPTR(HostTargetMap.HstPtrBegin), DPxPTR(HostTargetMap.TgtPtrBegin), - HostTargetMap.HstPtrEnd - HostTargetMap.HstPtrBegin, - HostTargetMap.dynRefCountToStr().c_str(), - HostTargetMap.holdRefCountToStr().c_str(), Info.getName(), - Info.getFilename(), Info.getLine(), Info.getColumn()); + DPxPTR(HDTT.HstPtrBegin), DPxPTR(HDTT.TgtPtrBegin), + HDTT.HstPtrEnd - HDTT.HstPtrBegin, HDTT.dynRefCountToStr().c_str(), + HDTT.holdRefCountToStr().c_str(), Info.getName(), Info.getFilename(), + Info.getLine(), Info.getColumn()); } - Device.DataMapMtx.unlock(); } ////////////////////////////////////////////////////////////////////////////////