// Used by targetDataBegin, targetDataEnd, targetDataUpdate and target.
// Return the target pointer begin (where the data will be moved).
-// Decrement the reference counter if called from targetDataEnd. The data is
-// excepted to be mapped already, so the result will never be new.
-TargetPointerResultTy
-DeviceTy::getTgtPtrBegin(void *HstPtrBegin, int64_t Size, bool &IsLast,
- bool UpdateRefCount, bool UseHoldRefCount,
- bool &IsHostPtr, bool MustContain, bool ForceDelete) {
- void *TargetPointer = NULL;
+// Decrement the reference counter if called from targetDataEnd.
+void *DeviceTy::getTgtPtrBegin(void *HstPtrBegin, int64_t Size, bool &IsLast,
+ bool UpdateRefCount, bool UseHoldRefCount,
+ bool &IsHostPtr, bool MustContain,
+ bool ForceDelete) {
+ void *rc = NULL;
IsHostPtr = false;
IsLast = false;
DataMapMtx.lock();
"Size=%" PRId64 ", DynRefCount=%s%s, HoldRefCount=%s%s\n",
DPxPTR(HstPtrBegin), DPxPTR(tp), Size, HT.dynRefCountToStr().c_str(),
DynRefCountAction, HT.holdRefCountToStr().c_str(), HoldRefCountAction);
- TargetPointer = (void *)tp;
+ rc = (void *)tp;
} else if (PM->RTLs.RequiresFlags & OMP_REQ_UNIFIED_SHARED_MEMORY) {
// If the value isn't found in the mapping and unified shared memory
// is on then it means we have stumbled upon a value which we need to
"memory\n",
DPxPTR((uintptr_t)HstPtrBegin), Size);
IsHostPtr = true;
- TargetPointer = HstPtrBegin;
+ rc = HstPtrBegin;
}
DataMapMtx.unlock();
- return {{false, IsHostPtr}, lr.Entry, TargetPointer};
+ return rc;
}
// Return the target pointer begin (where the data will be moved).
struct StatesTy {
StatesTy(uint64_t DRC, uint64_t HRC)
- : DynRefCount(DRC), HoldRefCount(HRC),
- MayContainAttachedPointers(false) {}
+ : DynRefCount(DRC), HoldRefCount(HRC) {}
/// The dynamic reference count is the standard reference count as of OpenMP
/// 4.5. The hold reference count is an OpenMP extension for the sake of
/// OpenACC support.
///
uint64_t DynRefCount;
uint64_t HoldRefCount;
-
- /// Boolean flag to remember if any subpart of the mapped region might be
- /// an attached pointer.
- bool MayContainAttachedPointers;
-
/// This mutex will be locked when data movement is issued. For targets that
/// doesn't support async data movement, this mutex can guarantee that after
/// it is released, memory region on the target is update to date. For
void lock() const { States->UpdateMtx.lock(); }
void unlock() const { States->UpdateMtx.unlock(); }
-
- void setMayContainAttachedPointers() const {
- States->MayContainAttachedPointers = true;
- }
- bool getMayContainAttachedPointers() const {
- return States->MayContainAttachedPointers;
- }
};
typedef uintptr_t HstPtrBeginTy;
bool HasCloseModifier, bool HasPresentModifier,
bool HasHoldModifier, AsyncInfoTy &AsyncInfo);
void *getTgtPtrBegin(void *HstPtrBegin, int64_t Size);
- TargetPointerResultTy getTgtPtrBegin(void *HstPtrBegin, int64_t Size,
- bool &IsLast, bool UpdateRefCount,
- bool UseHoldRefCount, bool &IsHostPtr,
- bool MustContain = false,
- bool ForceDelete = false);
+ void *getTgtPtrBegin(void *HstPtrBegin, int64_t Size, bool &IsLast,
+ bool UpdateRefCount, bool UseHoldRefCount,
+ bool &IsHostPtr, bool MustContain = false,
+ bool ForceDelete = false);
/// For the map entry for \p HstPtrBegin, decrement the reference count
/// specified by \p HasHoldModifier and, if the the total reference count is
/// then zero, deallocate the corresponding device storage and remove the map
#include "rtl.h"
#include <cassert>
-#include <cstdint>
#include <vector>
int AsyncInfoTy::synchronize() {
// create or update shadow pointers for this entry
Device.ShadowPtrMap[Pointer_HstPtrBegin] = {
HstPtrBase, PointerTgtPtrBegin, ExpectedTgtPtrBase};
- TPR.MapTableEntry->setMayContainAttachedPointers();
UpdateDevPtr = true;
}
DeallocTgtPtrInfo(void *HstPtr, int64_t Size, bool HasHoldModifier)
: HstPtrBegin(HstPtr), DataSize(Size), HasHoldModifier(HasHoldModifier) {}
};
-
-/// Apply \p CB to the shadow map pointer entries in the range \p Begin, to
-/// \p Begin + \p Size. \p CB is called with a locked shadow pointer map and the
-/// passed iterator can be updated. If the callback returns OFFLOAD_FAIL the
-/// rest of the map is not checked anymore.
-template <typename CBTy>
-static void applyToShadowMapEntries(DeviceTy &Device, CBTy CB, void *Begin,
- uintptr_t Size,
- const TargetPointerResultTy &TPR) {
- // If we have an object that is too small to hold a pointer subobject, no need
- // to do any checking.
- if (Size < sizeof(void *))
- return;
-
- // If the map entry for the object was never marked as containing attached
- // pointers, no need to do any checking.
- if (!TPR.MapTableEntry->getMayContainAttachedPointers())
- return;
-
- uintptr_t LB = (uintptr_t)Begin;
- uintptr_t UB = LB + Size;
- // Now we are looking into the shadow map so we need to lock it.
- Device.ShadowMtx.lock();
- for (ShadowPtrListTy::iterator Itr = Device.ShadowPtrMap.begin();
- Itr != Device.ShadowPtrMap.end();) {
- uintptr_t ShadowHstPtrAddr = (uintptr_t)Itr->first;
-
- // An STL map is sorted on its keys; use this property
- // to quickly determine when to break out of the loop.
- if (ShadowHstPtrAddr < LB) {
- ++Itr;
- continue;
- }
- if (ShadowHstPtrAddr >= UB)
- break;
-
- if (CB(Itr) == OFFLOAD_FAIL)
- break;
- }
- Device.ShadowMtx.unlock();
-}
-
} // namespace
/// Internal function to undo the mapping and retrieve the data from the device.
bool HasHoldModifier = ArgTypes[I] & OMP_TGT_MAPTYPE_OMPX_HOLD;
// If PTR_AND_OBJ, HstPtrBegin is address of pointee
- TargetPointerResultTy TPR = Device.getTgtPtrBegin(
+ void *TgtPtrBegin = Device.getTgtPtrBegin(
HstPtrBegin, DataSize, IsLast, UpdateRef, HasHoldModifier, IsHostPtr,
!IsImplicit, ForceDelete);
- void *TgtPtrBegin = TPR.TargetPointer;
if (!TgtPtrBegin && (DataSize || HasPresentModifier)) {
DP("Mapping does not exist (%s)\n",
(HasPresentModifier ? "'present' map type modifier" : "ignored"));
// need to restore the original host pointer values from their shadow
// copies. If the struct is going to be deallocated, remove any remaining
// shadow pointer entries for this struct.
- auto CB = [&](ShadowPtrListTy::iterator &Itr) {
+ uintptr_t LB = (uintptr_t)HstPtrBegin;
+ uintptr_t UB = (uintptr_t)HstPtrBegin + DataSize;
+ Device.ShadowMtx.lock();
+ for (ShadowPtrListTy::iterator Itr = Device.ShadowPtrMap.begin();
+ Itr != Device.ShadowPtrMap.end();) {
+ void **ShadowHstPtrAddr = (void **)Itr->first;
+
+ // An STL map is sorted on its keys; use this property
+ // to quickly determine when to break out of the loop.
+ if ((uintptr_t)ShadowHstPtrAddr < LB) {
+ ++Itr;
+ continue;
+ }
+ if ((uintptr_t)ShadowHstPtrAddr >= UB)
+ break;
+
// If we copied the struct to the host, we need to restore the pointer.
if (ArgTypes[I] & OMP_TGT_MAPTYPE_FROM) {
- void **ShadowHstPtrAddr = (void **)Itr->first;
DP("Restoring original host pointer value " DPxMOD " for host "
"pointer " DPxMOD "\n",
DPxPTR(Itr->second.HstPtrVal), DPxPTR(ShadowHstPtrAddr));
}
// If the struct is to be deallocated, remove the shadow entry.
if (DelEntry) {
- DP("Removing shadow pointer " DPxMOD "\n",
- DPxPTR(Itr->second.HstPtrVal));
+ DP("Removing shadow pointer " DPxMOD "\n", DPxPTR(ShadowHstPtrAddr));
Itr = Device.ShadowPtrMap.erase(Itr);
} else {
++Itr;
}
- return OFFLOAD_SUCCESS;
- };
- applyToShadowMapEntries(Device, CB, HstPtrBegin, DataSize, TPR);
+ }
+ Device.ShadowMtx.unlock();
// Add pointer to the buffer for later deallocation
if (DelEntry && !IsHostPtr)
int64_t ArgType, AsyncInfoTy &AsyncInfo) {
TIMESCOPE_WITH_IDENT(loc);
bool IsLast, IsHostPtr;
- TargetPointerResultTy TPR = Device.getTgtPtrBegin(
+ void *TgtPtrBegin = Device.getTgtPtrBegin(
HstPtrBegin, ArgSize, IsLast, /*UpdateRefCount=*/false,
/*UseHoldRefCount=*/false, IsHostPtr, /*MustContain=*/true);
- void *TgtPtrBegin = TPR.TargetPointer;
if (!TgtPtrBegin) {
DP("hst data:" DPxMOD " not found, becomes a noop\n", DPxPTR(HstPtrBegin));
if (ArgType & OMP_TGT_MAPTYPE_PRESENT) {
return OFFLOAD_FAIL;
}
- auto CB = [&](ShadowPtrListTy::iterator &Itr) {
- void **ShadowHstPtrAddr = (void **)Itr->first;
+ uintptr_t LB = (uintptr_t)HstPtrBegin;
+ uintptr_t UB = (uintptr_t)HstPtrBegin + ArgSize;
+ Device.ShadowMtx.lock();
+ for (ShadowPtrListTy::iterator IT = Device.ShadowPtrMap.begin();
+ IT != Device.ShadowPtrMap.end(); ++IT) {
+ void **ShadowHstPtrAddr = (void **)IT->first;
+ if ((uintptr_t)ShadowHstPtrAddr < LB)
+ continue;
+ if ((uintptr_t)ShadowHstPtrAddr >= UB)
+ break;
DP("Restoring original host pointer value " DPxMOD
" for host pointer " DPxMOD "\n",
- DPxPTR(Itr->second.HstPtrVal), DPxPTR(ShadowHstPtrAddr));
- *ShadowHstPtrAddr = Itr->second.HstPtrVal;
- return OFFLOAD_SUCCESS;
- };
- applyToShadowMapEntries(Device, CB, HstPtrBegin, ArgSize, TPR);
+ DPxPTR(IT->second.HstPtrVal), DPxPTR(ShadowHstPtrAddr));
+ *ShadowHstPtrAddr = IT->second.HstPtrVal;
+ }
+ Device.ShadowMtx.unlock();
}
if (ArgType & OMP_TGT_MAPTYPE_TO) {
return OFFLOAD_FAIL;
}
- auto CB = [&](ShadowPtrListTy::iterator &Itr) {
+ uintptr_t LB = (uintptr_t)HstPtrBegin;
+ uintptr_t UB = (uintptr_t)HstPtrBegin + ArgSize;
+ Device.ShadowMtx.lock();
+ for (ShadowPtrListTy::iterator IT = Device.ShadowPtrMap.begin();
+ IT != Device.ShadowPtrMap.end(); ++IT) {
+ void **ShadowHstPtrAddr = (void **)IT->first;
+ if ((uintptr_t)ShadowHstPtrAddr < LB)
+ continue;
+ if ((uintptr_t)ShadowHstPtrAddr >= UB)
+ break;
DP("Restoring original target pointer value " DPxMOD " for target "
"pointer " DPxMOD "\n",
- DPxPTR(Itr->second.TgtPtrVal), DPxPTR(Itr->second.TgtPtrAddr));
- Ret = Device.submitData(Itr->second.TgtPtrAddr, &Itr->second.TgtPtrVal,
+ DPxPTR(IT->second.TgtPtrVal), DPxPTR(IT->second.TgtPtrAddr));
+ Ret = Device.submitData(IT->second.TgtPtrAddr, &IT->second.TgtPtrVal,
sizeof(void *), AsyncInfo);
- if (Ret != OFFLOAD_SUCCESS)
+ if (Ret != OFFLOAD_SUCCESS) {
REPORT("Copying data to device failed.\n");
- return Ret;
- };
- applyToShadowMapEntries(Device, CB, HstPtrBegin, ArgSize, TPR);
+ Device.ShadowMtx.unlock();
+ return OFFLOAD_FAIL;
+ }
+ }
+ Device.ShadowMtx.unlock();
}
return OFFLOAD_SUCCESS;
}
uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase;
void *TgtPtrBegin = (void *)((uintptr_t)TgtPtrBase + Delta);
void *&PointerTgtPtrBegin = AsyncInfo.getVoidPtrLocation();
- TargetPointerResultTy TPR = Device.getTgtPtrBegin(
+ PointerTgtPtrBegin = Device.getTgtPtrBegin(
HstPtrVal, ArgSizes[I], IsLast, /*UpdateRefCount=*/false,
/*UseHoldRefCount=*/false, IsHostPtr);
- PointerTgtPtrBegin = TPR.TargetPointer;
if (!PointerTgtPtrBegin) {
DP("No lambda captured variable mapped (" DPxMOD ") - ignored\n",
DPxPTR(HstPtrVal));
map_var_info_t HstPtrName = (!ArgNames) ? nullptr : ArgNames[I];
ptrdiff_t TgtBaseOffset;
bool IsLast, IsHostPtr; // unused.
- TargetPointerResultTy TPR;
if (ArgTypes[I] & OMP_TGT_MAPTYPE_LITERAL) {
DP("Forwarding first-private value " DPxMOD " to the target construct\n",
DPxPTR(HstPtrBase));
} else {
if (ArgTypes[I] & OMP_TGT_MAPTYPE_PTR_AND_OBJ)
HstPtrBase = *reinterpret_cast<void **>(HstPtrBase);
- TPR = Device.getTgtPtrBegin(HstPtrBegin, ArgSizes[I], IsLast,
- /*UpdateRefCount=*/false,
- /*UseHoldRefCount=*/false, IsHostPtr);
- TgtPtrBegin = TPR.TargetPointer;
+ TgtPtrBegin = Device.getTgtPtrBegin(HstPtrBegin, ArgSizes[I], IsLast,
+ /*UpdateRefCount=*/false,
+ /*UseHoldRefCount=*/false, IsHostPtr);
TgtBaseOffset = (intptr_t)HstPtrBase - (intptr_t)HstPtrBegin;
#ifdef OMPTARGET_DEBUG
void *TgtPtrBase = (void *)((intptr_t)TgtPtrBegin + TgtBaseOffset);