Skip to content

Commit

Permalink
Add memfence before unsetting bit
Browse files Browse the repository at this point in the history
  • Loading branch information
chillenzer committed Feb 5, 2025
1 parent 218acec commit c6994b9
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,16 @@ namespace mallocMC::CreationPolicies::FlatterScatterAlloc
"to a valid chunk or it is not marked as allocated."};
}
#endif // NDEBUG

// CAUTION: This memfence is of utmost importance! As we are allowing a re-use of the chunk we're about to
// free, we need to make sure that any memory operation from the previous thread is executed before we can
// safely consider it free. If this is missing, an extended (non-atomic) write operation might not yet have
// finished when we unset the bit. In such a case, another thread might start using the memory while we're
// still writing to it, thus corrupting the new thread's data. It might even lead to us overwriting the
// bitmask itself, if the chunk size (and thereby the extent of the bitmask) changes before we finish.
// (The latter scenario might be excluded by other mem_fences in the code.) If a read is pending, the old
// thread might read data from the new thread leading to inconsistent information in the first thread.
alpaka::mem_fence(acc, alpaka::memory_scope::Device{});
bitField().unset(acc, chunkIndex);
}

Expand Down
10 changes: 10 additions & 0 deletions include/mallocMC/creationPolicies/Scatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,16 @@ namespace mallocMC
template<typename AlpakaAcc>
ALPAKA_FN_ACC void deallocChunked(AlpakaAcc const& acc, void* mem, uint32 page, uint32 chunksize)
{
// CAUTION: This memfence is of utmost importance! As we are allowing a re-use of the chunk we're about
// to free, we need to make sure that any memory operation from the previous thread is executed before
// we can safely consider it free. If this is missing, an extended (non-atomic) write operation might
// not yet have finished when we unset the bit. In such a case, another thread might start using the
// memory while we're still writing to it, thus corrupting the new thread's data. It might even lead to
// us overwriting the bitmask itself, if the chunk size (and thereby the extent of the bitmask) changes
// before we finish. (The latter scenario might be excluded by other mem_fences in the code.) If a read
// is pending, the old thread might read data from the new thread leading to inconsistent information
// in the first thread.
alpaka::mem_fence(acc, alpaka::memory_scope::Device{});
auto const inpage_offset = static_cast<uint32>((char*) mem - _page[page].data);
if(chunksize <= HierarchyThreshold)
{
Expand Down

0 comments on commit c6994b9

Please sign in to comment.