Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

only allocate memory if needed #50

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion redGrapes/util/atomic_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ struct AtomicList
return chunk_capacity + get_controlblock_size();
}

/* initializes a new chunk
/* allocate a new item and add it to the list
*
* @{
*/
auto allocate_item()
{
Expand All @@ -182,6 +184,26 @@ struct AtomicList
return append_item( std::allocate_shared< ItemControlBlock >( chunk_alloc, blk ) );
}

/** allocate the first item if the list is empty
*
* If more than one thread tries to add the first item only one thread will successfully add an item.
*/
bool try_allocate_first_item()
{
TRACE_EVENT("Allocator", "AtomicList::allocate_first_item()");
StaticAlloc<void> chunk_alloc( this->alloc, get_chunk_allocsize() );

// this block will contain the Item-data of ItemControlBlock
memory::Block blk{
.ptr = (uintptr_t)chunk_alloc.ptr + get_controlblock_size(),
.len = chunk_capacity - get_controlblock_size()
};

auto sharedChunk = std::allocate_shared< ItemControlBlock >( chunk_alloc, blk );
return try_append_first_item( std::move(sharedChunk) );
}
/** @} */

template < bool is_const = false >
struct BackwardIterator
{
Expand Down Expand Up @@ -297,7 +319,15 @@ struct AtomicList
return MutBackwardIterator{ old_head };
}

// append the first head item if not already exists
bool try_append_first_item( std::shared_ptr< ItemControlBlock > new_head )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still possible to append two items with try_append_first_item() , because it is still an ordinary append function just that it fails if two calls happen concurrently in such a way that one thread messes with the already read-out value of head.

If two threads call try_append_first_item() with such scheduling that the second thread initialized old_head after the first thread already wrote to head, the second thread will simply append another item after head.

it should be like

std::shared_ptr< ItemControlBlock > expected( nullptr );
std::shared_ptr< ItemControlBlock > const & desired = new_head;

std::atomic_compare_exchange_strong<ItemControlBlock>( &head, &expected, desired );

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes this was my intention but wrote it during a meeting and than I forgot to add the empty element as old. I will update the branch with your suggestion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added your suggestion and forced push the change

{
TRACE_EVENT("Allocator", "AtomicList::append_first_item()");

std::shared_ptr< ItemControlBlock > expected( nullptr );
std::shared_ptr< ItemControlBlock > const & desired = new_head;
return std::atomic_compare_exchange_strong<ItemControlBlock>( &head, &expected, desired );
}
};

} // namespace memory
Expand Down
7 changes: 2 additions & 5 deletions redGrapes/util/chunked_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,7 @@ struct ChunkedList
public:
ChunkedList( Allocator && alloc )
: chunks( std::move(alloc), T_chunk_size * sizeof(Item) + sizeof(Chunk) )
{
chunks.allocate_item();
}
{}

ChunkedList( ChunkedList && other ) = default;
ChunkedList( Allocator && alloc, ChunkedList const & other )
Expand Down Expand Up @@ -467,9 +465,8 @@ struct ChunkedList
}
else
{
throw std::runtime_error("chunk_list: invalid state, there should always be at least one chunk available.");
chunks.try_allocate_first_item();
}

}
}

Expand Down
Loading