From 65840ee39c5607498c83988e9234535d49a4a60f Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Mon, 27 Jan 2020 18:04:23 -0800 Subject: [PATCH 1/2] Avoid std::atomic_init deprecated by P0883. Resolves #139 --- include/cppcoro/multi_producer_sequencer.hpp | 2 ++ lib/cancellation_state.cpp | 21 ++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/cppcoro/multi_producer_sequencer.hpp b/include/cppcoro/multi_producer_sequencer.hpp index e13bfe6c..6806070d 100644 --- a/include/cppcoro/multi_producer_sequencer.hpp +++ b/include/cppcoro/multi_producer_sequencer.hpp @@ -508,11 +508,13 @@ namespace cppcoro constexpr unsigned_diff_t maxSize = static_cast(std::numeric_limits::max()); assert(bufferSize <= maxSize); +#ifndef __cpp_lib_atomic_value_initialization SEQUENCE seq = initialSequence - (bufferSize - 1); do { std::atomic_init(&m_published[seq & m_sequenceMask], seq); } while (seq++ != initialSequence); +#endif // !__cpp_lib_atomic_value_initialization } template diff --git a/lib/cancellation_state.cpp b/lib/cancellation_state.cpp index e4118f82..a81123c8 100644 --- a/lib/cancellation_state.cpp +++ b/lib/cancellation_state.cpp @@ -79,13 +79,13 @@ cppcoro::detail::cancellation_registration_list_chunk::allocate(std::uint32_t en throw std::bad_alloc{}; } - std::atomic_init(&chunk->m_nextChunk, static_cast(nullptr)); + ::new (&chunk->m_nextChunk) std::atomic(nullptr); chunk->m_prevChunk = nullptr; - std::atomic_init(&chunk->m_approximateFreeCount, static_cast(entryCount - 1)); + ::new (&chunk->m_approximateFreeCount) std::atomic(static_cast(entryCount - 1)); chunk->m_entryCount = entryCount; for (std::uint32_t i = 0; i < entryCount; ++i) { - std::atomic_init(&chunk->m_entries[i], static_cast(nullptr)); + ::new (&chunk->m_entries[i]) std::atomic(nullptr); } return chunk; @@ -112,14 +112,15 @@ cppcoro::detail::cancellation_registration_list::allocate() throw std::bad_alloc{}; } - std::atomic_init(&bucket->m_approximateTail, &bucket->m_headChunk); - std::atomic_init(&bucket->m_headChunk.m_nextChunk, static_cast(nullptr)); + ::new (&bucket->m_approximateTail) std::atomic(&bucket->m_headChunk); + ::new (&bucket->m_headChunk.m_nextChunk) std::atomic(nullptr); bucket->m_headChunk.m_prevChunk = nullptr; - std::atomic_init(&bucket->m_headChunk.m_approximateFreeCount, static_cast(initialChunkSize - 1)); + ::new (&bucket->m_headChunk.m_approximateFreeCount) + std::atomic(static_cast(initialChunkSize - 1)); bucket->m_headChunk.m_entryCount = initialChunkSize; for (std::uint32_t i = 0; i < initialChunkSize; ++i) { - std::atomic_init(&bucket->m_headChunk.m_entries[i], static_cast(nullptr)); + ::new (&bucket->m_headChunk.m_entries[i]) std::atomic(nullptr); } return bucket; @@ -158,7 +159,7 @@ cppcoro::detail::cancellation_registration_state::allocate() state->m_listCount = listCount; for (std::uint32_t i = 0; i < listCount; ++i) { - std::atomic_init(&state->m_lists[i], static_cast(nullptr)); + ::new (&state->m_lists[i]) std::atomic(nullptr); } return state; @@ -187,7 +188,7 @@ cppcoro::detail::cancellation_registration_state::add_registration( // Pre-claim the first slot. registration->m_chunk = &newList->m_headChunk; registration->m_entryIndex = 0; - std::atomic_init(&newList->m_headChunk.m_entries[0], registration); + ::new (&newList->m_headChunk.m_entries[0]) std::atomic(registration); if (listPtr.compare_exchange_strong( list, @@ -305,7 +306,7 @@ cppcoro::detail::cancellation_registration_state::add_registration( // Pre-allocate first slot. registration->m_chunk = newChunk; registration->m_entryIndex = 0; - std::atomic_init(&newChunk->m_entries[0], registration); + ::new (&newChunk->m_entries[0]) std::atomic(registration); cancellation_registration_list_chunk* oldNext = nullptr; if (lastChunk->m_nextChunk.compare_exchange_strong( From 6d866f92e3394126ade8d33cb3852e9e2e1cdc7f Mon Sep 17 00:00:00 2001 From: Billy Robert O'Neal III Date: Tue, 28 Jan 2020 12:47:31 -0800 Subject: [PATCH 2/2] Restore initialization of the array in multi_producer_sequencer.hpp. --- include/cppcoro/multi_producer_sequencer.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/cppcoro/multi_producer_sequencer.hpp b/include/cppcoro/multi_producer_sequencer.hpp index 6806070d..72589c3d 100644 --- a/include/cppcoro/multi_producer_sequencer.hpp +++ b/include/cppcoro/multi_producer_sequencer.hpp @@ -508,13 +508,15 @@ namespace cppcoro constexpr unsigned_diff_t maxSize = static_cast(std::numeric_limits::max()); assert(bufferSize <= maxSize); -#ifndef __cpp_lib_atomic_value_initialization SEQUENCE seq = initialSequence - (bufferSize - 1); do { +#ifdef __cpp_lib_atomic_value_initialization + m_published[seq & m_sequenceMask].store(seq, std::memory_order_relaxed); +#else // ^^^ __cpp_lib_atomic_value_initialization // !__cpp_lib_atomic_value_initialization vvv std::atomic_init(&m_published[seq & m_sequenceMask], seq); - } while (seq++ != initialSequence); #endif // !__cpp_lib_atomic_value_initialization + } while (seq++ != initialSequence); } template