From e94b884aee33996dbaa4f55b068e288c654fc854 Mon Sep 17 00:00:00 2001 From: Christian Kern Date: Fri, 23 Oct 2015 11:15:49 +0200 Subject: [PATCH] fix for jira ticket #525 --- containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h | 39 +++++++++++++++++++++++++++++++++++---- containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h | 14 ++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h b/containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h index 2049174..73485e4 100644 --- a/containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h +++ b/containers_cpp/include/embb/containers/internal/lock_free_tree_value_pool-inl.h @@ -213,11 +213,28 @@ LockFreeTreeValuePool(ForwardIterator first, ForwardIterator last) { // Size of binary tree without the leaves tree_size = size - 1; + // make sure, signed values are not negative + assert(tree_size >= 0); + assert(real_size >= 0); + + size_t tree_size_unsigned = static_cast(tree_size); + size_t real_size_unsigned = static_cast(real_size); + // Pool stores elements of type T - pool = poolAllocator.allocate(static_cast(real_size)); + pool = poolAllocator.allocate(real_size_unsigned); + + // invoke inplace new for each pool element + for (size_t i = 0; i != real_size_unsigned; ++i) { + new (&pool[i]) embb::base::Atomic(); + } // Tree holds the counter of not allocated elements - tree = treeAllocator.allocate(static_cast(tree_size)); + tree = treeAllocator.allocate(tree_size_unsigned); + + // invoke inplace new for each tree element + for (size_t i = 0; i != tree_size_unsigned; ++i) { + new (&tree[i]) embb::base::Atomic(); + } int i = 0; @@ -234,8 +251,22 @@ template LockFreeTreeValuePool:: ~LockFreeTreeValuePool() { - poolAllocator.deallocate(pool, static_cast(real_size)); - treeAllocator.deallocate(tree, static_cast(tree_size)); + size_t tree_size_unsigned = static_cast(tree_size); + size_t real_size_unsigned = static_cast(real_size); + + poolAllocator.deallocate(pool, real_size_unsigned); + + // invoke destructor for each pool element + for (size_t i = 0; i != real_size_unsigned; ++i) { + pool[i].~Atomic(); + } + + treeAllocator.deallocate(tree, tree_size_unsigned); + + // invoke destructor for each tree element + for (size_t i = 0; i != tree_size_unsigned; ++i) { + tree[i].~Atomic(); + } } } // namespace containers diff --git a/containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h b/containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h index 1453f1f..bef96c7 100644 --- a/containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h +++ b/containers_cpp/include/embb/containers/internal/wait_free_array_value_pool-inl.h @@ -66,9 +66,17 @@ WaitFreeArrayValuePool(ForwardIterator first, ForwardIterator last) { size = static_cast(dist); + // conversion may result in negative number. check! + assert(size >= 0); + // Use the allocator to allocate an array of size dist pool = allocator.allocate(dist); + // invoke inplace new for each pool element + for ( size_t i = 0; i != dist; ++i ) { + new (&pool[i]) embb::base::Atomic(); + } + int i = 0; // Store the elements of the range @@ -79,6 +87,12 @@ WaitFreeArrayValuePool(ForwardIterator first, ForwardIterator last) { template WaitFreeArrayValuePool::~WaitFreeArrayValuePool() { + // invoke destructor for each pool element + for (int i = 0; i != size; ++i) { + pool[i].~Atomic(); + } + + // free memory allocator.deallocate(pool, (size_t)size); } } // namespace containers -- libgit2 0.26.0