Merge topic 'stolen_arrays_can_still_be_used_as_input'

c385b21a StorageBasic is now treated like users memory after being stolen.

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !891
This commit is contained in:
Robert Maynard 2017-08-22 13:09:55 +00:00 committed by Kitware Robot
commit 0cbc3db016
4 changed files with 37 additions and 21 deletions

@ -186,8 +186,13 @@ public:
using AllocatorType = AlignedAllocator<ValueType, VTKM_CACHE_LINE_SIZE>;
public:
/// \brief construct storage that VTK-m is responsible for
VTKM_CONT
Storage(const ValueType* array = nullptr, vtkm::Id numberOfValues = 0);
Storage();
/// \brief construct storage that VTK-m is not responsible for
VTKM_CONT
Storage(const ValueType* array, vtkm::Id numberOfValues = 0);
VTKM_CONT
~Storage();
@ -245,15 +250,22 @@ public:
/// \brief Take the reference away from this object.
///
/// This method returns the pointer to the array held by this array. It then
/// clears the internal array pointer to nullptr, thereby ensuring that the
/// Storage will never deallocate the array. This is helpful for taking a
/// reference for an array created internally by VTK-m and not having to keep
/// a VTK-m object around. Obviously the caller becomes responsible for
/// destroying the memory.
/// clears the internal ownership flags, thereby ensuring that the
/// Storage will never deallocate the array or be able to reallocate it. This
/// is helpful for taking a reference for an array created internally by
/// VTK-m and not having to keep a VTK-m object around. Obviously the caller
/// becomes responsible for destroying the memory.
///
VTKM_CONT
ValueType* StealArray();
/// \brief Returns if vtkm will deallocate this memory. VTK-m StorageBasic
/// is designed that VTK-m will not deallocate user passed memory, or
/// instances that have been stolen (\c StealArray)
VTKM_CONT
bool WillDeallocate() const { return this->DeallocateOnRelease; }
VTKM_CONT
void* GetBasePointer() const final { return static_cast<void*>(this->Array); }
@ -274,7 +286,6 @@ private:
vtkm::Id NumberOfValues;
vtkm::Id AllocatedSize;
bool DeallocateOnRelease;
bool UserProvidedMemory;
};
} // namespace internal

@ -29,13 +29,21 @@ namespace cont
namespace internal
{
template <typename T>
Storage<T, vtkm::cont::StorageTagBasic>::Storage()
: Array(nullptr)
, NumberOfValues(0)
, AllocatedSize(0)
, DeallocateOnRelease(true)
{
}
template <typename T>
Storage<T, vtkm::cont::StorageTagBasic>::Storage(const T* array, vtkm::Id numberOfValues)
: Array(const_cast<T*>(array))
, NumberOfValues(numberOfValues)
, AllocatedSize(numberOfValues)
, DeallocateOnRelease(false)
, UserProvidedMemory(array == nullptr ? false : true)
, DeallocateOnRelease(array == nullptr ? true : false)
{
}
@ -50,8 +58,7 @@ Storage<T, vtkm::cont::StorageTagBasic>::Storage(const Storage<T, StorageTagBasi
: Array(src.Array)
, NumberOfValues(src.NumberOfValues)
, AllocatedSize(src.AllocatedSize)
, DeallocateOnRelease(false)
, UserProvidedMemory(src.UserProvidedMemory)
, DeallocateOnRelease(src.DeallocateOnRelease)
{
if (src.DeallocateOnRelease)
{
@ -77,7 +84,6 @@ Storage<T, vtkm::cont::StorageTagBasic>& Storage<T, vtkm::cont::StorageTagBasic>
this->NumberOfValues = src.NumberOfValues;
this->AllocatedSize = src.AllocatedSize;
this->DeallocateOnRelease = src.DeallocateOnRelease;
this->UserProvidedMemory = src.UserProvidedMemory;
return *this;
}
@ -139,7 +145,7 @@ void Storage<T, vtkm::cont::StorageTagBasic>::AllocateBytes(vtkm::Id numberOfByt
return;
}
if (this->UserProvidedMemory)
if (!this->DeallocateOnRelease)
{
throw vtkm::cont::ErrorBadValue("User allocated arrays cannot be reallocated.");
}
@ -170,7 +176,6 @@ void Storage<T, vtkm::cont::StorageTagBasic>::AllocateBytes(vtkm::Id numberOfByt
}
this->DeallocateOnRelease = true;
this->UserProvidedMemory = false;
}
template <typename T>
@ -193,11 +198,8 @@ void Storage<T, vtkm::cont::StorageTagBasic>::ShrinkBytes(vtkm::Id numberOfBytes
template <typename T>
T* Storage<T, vtkm::cont::StorageTagBasic>::StealArray()
{
T* saveArray = this->Array;
this->Array = nullptr;
this->NumberOfValues = 0;
this->AllocatedSize = 0;
return saveArray;
this->DeallocateOnRelease = false;
return this->Array;
}
} // namespace internal

@ -133,8 +133,11 @@ struct TemplatedTests
VTKM_TEST_ASSERT(stealMyArray.GetNumberOfValues() == ARRAY_SIZE,
"Array not properly allocated.");
// This call steals the array and prevents deallocation.
VTKM_TEST_ASSERT(stealMyArray.WillDeallocate() == true,
"Array to be stolen needs to be owned by VTK-m");
stolenArray = stealMyArray.StealArray();
VTKM_TEST_ASSERT(stealMyArray.GetNumberOfValues() == 0, "StealArray did not let go of array.");
VTKM_TEST_ASSERT(stealMyArray.WillDeallocate() == false,
"Stolen array should not be owned by VTK-m");
return stolenArray;
}

@ -58,7 +58,7 @@ public:
VTKM_CONT
AtomicArray()
: AtomicImplementation(vtkm::cont::make_ArrayHandle((T*)nullptr, 0))
: AtomicImplementation((vtkm::cont::ArrayHandle<T>()))
{
}