Skip to content

Commit

Permalink
Use ManualConstructor(AlignedMemory) instead of std::aligned_storage …
Browse files Browse the repository at this point in the history
…which has been deprecated in C++23
  • Loading branch information
chenBright committed Aug 10, 2024
1 parent c709c96 commit a7e4410
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/brpc/versioned_ref_with_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ friend void DereferenceVersionedRefWithId<>(T* r);
// This is also the version encoded in VRefId.
// * Failed version: = created version + 1, SetFailed()-ed but returned.
// * Other versions: the socket is already recycled.
butil::atomic<uint64_t> BAIDU_CACHELINE_ALIGNMENT _versioned_ref;
BAIDU_CACHELINE_ALIGNMENT butil::atomic<uint64_t> _versioned_ref;
// The unique identifier.
VRefId _this_id;
// Indicates whether additional reference has increased,
Expand Down
4 changes: 4 additions & 0 deletions src/butil/compiler_specific.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,15 @@
// Use like:
// class ALIGNAS(16) MyClass { ... }
// ALIGNAS(16) int array[4];
#if (__cplusplus >= 201103L)
# define ALIGNAS(byte_alignment) alignas(byte_alignment)
#elif
#if defined(COMPILER_MSVC)
# define ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
#elif defined(COMPILER_GCC)
# define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
#endif
#endif

// Return the byte alignment of the given type (available at compile time). Use
// sizeof(type) prior to checking __alignof to workaround Visual C++ bug:
Expand Down
24 changes: 14 additions & 10 deletions src/butil/containers/flat_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
#define BUTIL_FLAT_MAP_H

#include <stdint.h>
#include <cstddef>
#include <functional>
#include <iostream> // std::ostream
#include <type_traits> // std::aligned_storage
Expand All @@ -105,6 +106,7 @@
#include "butil/bit_array.h" // bit_array_*
#include "butil/strings/string_piece.h" // StringPiece
#include "butil/memory/scope_guard.h"
#include "butil/memory/manual_constructor.h"

namespace butil {

Expand Down Expand Up @@ -265,24 +267,26 @@ class FlatMap {
BucketInfo bucket_info() const;

struct Bucket {
explicit Bucket(const _K& k) : next(NULL)
{ new (&element_spaces) Element(k); }
Bucket(const Bucket& other) : next(NULL)
{ new (&element_spaces) Element(other.element()); }
explicit Bucket(const _K& k) : next(NULL) {
element_.Init(k);
}
Bucket(const Bucket& other) : next(NULL) {
element_.Init(other.element());
}

bool is_valid() const { return next != (const Bucket*)-1UL; }
void set_invalid() { next = (Bucket*)-1UL; }
// NOTE: Only be called when is_valid() is true.
Element& element() {
void* spaces = &element_spaces; // Suppress strict-aliasing
return *reinterpret_cast<Element*>(spaces);
return *element_;
}
const Element& element() const {
const void* spaces = &element_spaces;
return *reinterpret_cast<const Element*>(spaces);
return *element_;
}
Bucket *next;
typename std::aligned_storage<sizeof(Element), alignof(Element)>::type
element_spaces;

private:
ManualConstructor<Element> element_;
};

allocator_type& get_allocator() { return _pool.get_allocator(); }
Expand Down
9 changes: 5 additions & 4 deletions src/butil/containers/mpsc_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "butil/object_pool.h"
#include "butil/type_traits.h"
#include "butil/memory/manual_constructor.h"

namespace butil {

Expand All @@ -32,7 +33,7 @@ struct BAIDU_CACHELINE_ALIGNMENT MPSCQueueNode {
static MPSCQueueNode* const UNCONNECTED;

MPSCQueueNode* next{NULL};
char data_mem[sizeof(T)]{};
ManualConstructor<T> data_mem;

};

Expand Down Expand Up @@ -95,15 +96,15 @@ template <typename T, typename Alloc>
void MPSCQueue<T, Alloc>::Enqueue(typename add_const_reference<T>::type data) {
auto node = (MPSCQueueNode<T>*)_alloc.Alloc();
node->next = MPSCQueueNode<T>::UNCONNECTED;
new ((void*)&node->data_mem) T(data);
node->data_mem.Init(data);
EnqueueImpl(node);
}

template <typename T, typename Alloc>
void MPSCQueue<T, Alloc>::Enqueue(T&& data) {
auto node = (MPSCQueueNode<T>*)_alloc.Alloc();
node->next = MPSCQueueNode<T>::UNCONNECTED;
new ((void*)&node->data_mem) T(std::forward<T>(data));
node->data_mem.Init(data);
EnqueueImpl(node);
}

Expand Down Expand Up @@ -137,7 +138,7 @@ bool MPSCQueue<T, Alloc>::DequeueImpl(T* data) {

_cur_enqueue_node.store(NULL, memory_order_relaxed);
if (data) {
auto mem = (T* const)node->data_mem;
auto mem = (T* const)node->data_mem.get();
*data = std::move(*mem);
}
MPSCQueueNode<T>* old_node = node;
Expand Down
37 changes: 20 additions & 17 deletions src/butil/memory/aligned_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,27 @@ namespace butil {
template <size_t Size, size_t ByteAlignment>
struct AlignedMemory {};

#define BUTIL_DECL_ALIGNED_MEMORY(byte_alignment) \
template <size_t Size> \
class AlignedMemory<Size, byte_alignment> { \
public: \
ALIGNAS(byte_alignment) uint8_t data_[Size]; \
void* void_data() { return static_cast<void*>(data_); } \
const void* void_data() const { \
return static_cast<const void*>(data_); \
} \
template<typename Type> \
// std::aligned_storage has been deprecated in C++23,
// because aligned_* are harmful to codebases and should not be used.
// For details, see https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1413r3.pdf
#define BUTIL_DECL_ALIGNED_MEMORY(byte_alignment) \
template <size_t Size> \
class AlignedMemory<Size, byte_alignment> { \
public: \
ALIGNAS(byte_alignment) uint8_t data_[Size]; \
void* void_data() { return static_cast<void*>(data_); } \
const void* void_data() const { \
return static_cast<const void*>(data_); \
} \
template<typename Type> \
Type* data_as() { return static_cast<Type*>(void_data()); } \
template<typename Type> \
const Type* data_as() const { \
return static_cast<const Type*>(void_data()); \
} \
private: \
void* operator new(size_t); \
void operator delete(void*); \
template<typename Type> \
const Type* data_as() const { \
return static_cast<const Type*>(void_data()); \
} \
private: \
void* operator new(size_t); \
void operator delete(void*); \
}

// Specialization for all alignments is required because MSVC (as of VS 2008)
Expand Down

0 comments on commit a7e4410

Please sign in to comment.