diff --git a/3rdParty/velocypack/include/velocypack/Basics.h b/3rdParty/velocypack/include/velocypack/Basics.h index 2b13c68c8c..5bf057acc9 100644 --- a/3rdParty/velocypack/include/velocypack/Basics.h +++ b/3rdParty/velocypack/include/velocypack/Basics.h @@ -54,9 +54,9 @@ class NonCopyable { // prevent heap allocation struct NonHeapAllocatable { - void* operator new(std::size_t) throw(std::bad_alloc) = delete; + void* operator new(std::size_t) = delete; void operator delete(void*) noexcept = delete; - void* operator new[](std::size_t) throw(std::bad_alloc) = delete; + void* operator new[](std::size_t) = delete; void operator delete[](void*) noexcept = delete; }; diff --git a/lib/Basics/DataProtector.h b/lib/Basics/DataProtector.h index bf240e0caa..bbf63af47a 100644 --- a/lib/Basics/DataProtector.h +++ b/lib/Basics/DataProtector.h @@ -65,22 +65,24 @@ namespace basics { /// instantiation for all values of Nr used in the executable. //////////////////////////////////////////////////////////////////////////////// -#define DATA_PROTECTOR_MULTIPLICITY 64 - // TODO: Make this a template again once everybody has gcc >= 4.9.2 // template class DataProtector { + static constexpr int DATA_PROTECTOR_MULTIPLICITY = 64; + #ifdef _WIN32 - struct Entry { // 64 is the size of a cache line, + struct Entry { // 64 is the size of a cache line, #else - struct alignas(64) Entry { // 64 is the size of a cache line, + struct alignas(64) Entry { // 64 is the size of a cache line, #endif // it is important that different list entries lie in different // cache lines. std::atomic _count; + + Entry() : _count(0) {} }; - Entry* _list; + typename std::aligned_storage::type _list[DATA_PROTECTOR_MULTIPLICITY]; static std::atomic _last; @@ -116,25 +118,29 @@ class DataProtector { UnUser() = delete; }; - DataProtector() : _list(nullptr) { - _list = new Entry[DATA_PROTECTOR_MULTIPLICITY]; - // Just to be sure: - for (size_t i = 0; i < DATA_PROTECTOR_MULTIPLICITY; i++) { - _list[i]._count = 0; + DataProtector() { + // initialize uninitialized memory + for (int i = 0; i < DATA_PROTECTOR_MULTIPLICITY; i++) { + new (_list + i) Entry; } } - ~DataProtector() { delete[] _list; } + ~DataProtector() { + for (int i = 0; i < DATA_PROTECTOR_MULTIPLICITY; i++) { + reinterpret_cast(_list + i)->~Entry(); + } + } UnUser use() { int id = getMyId(); - _list[id]._count++; // this is implicitly using memory_order_seq_cst + // this is implicitly using memory_order_seq_cst + reinterpret_cast(_list + id)->_count++; return UnUser(this, id); // return value optimization! } void scan() { - for (size_t i = 0; i < DATA_PROTECTOR_MULTIPLICITY; i++) { - while (_list[i]._count > 0) { + for (int i = 0; i < DATA_PROTECTOR_MULTIPLICITY; i++) { + while (reinterpret_cast(_list + i)->_count > 0) { // let other threads do some work while we're waiting usleep(250); } @@ -143,7 +149,8 @@ class DataProtector { private: void unUse(int id) { - _list[id]._count--; // this is implicitly using memory_order_seq_cst + // this is implicitly using memory_order_seq_cst + reinterpret_cast(_list + id)->_count--; } int getMyId();