dtoolbase: Change DeletedBufferChain to use new C++11-style atomics

This commit is contained in:
rdb 2022-02-04 20:51:53 +01:00
parent 7da70cf939
commit 39d69f13de
3 changed files with 16 additions and 13 deletions

View File

@ -27,7 +27,7 @@ validate(void *ptr) {
#if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN) #if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN)
const ObjectNode *obj = buffer_to_node(ptr); const ObjectNode *obj = buffer_to_node(ptr);
return AtomicAdjust::get(obj->_flag) == DCF_alive; return obj->_flag.load(std::memory_order_relaxed) == DCF_alive;
#else #else
return true; return true;
#endif // USE_DELETEDCHAINFLAG #endif // USE_DELETEDCHAINFLAG

View File

@ -50,8 +50,8 @@ allocate(size_t size, TypeHandle type_handle) {
_lock.unlock(); _lock.unlock();
#ifdef USE_DELETEDCHAINFLAG #ifdef USE_DELETEDCHAINFLAG
assert(obj->_flag == (AtomicAdjust::Integer)DCF_deleted); DeletedChainFlag orig_flag = obj->_flag.exchange(DCF_alive, std::memory_order_relaxed);
obj->_flag = DCF_alive; assert(orig_flag == DCF_deleted);
#endif // USE_DELETEDCHAINFLAG #endif // USE_DELETEDCHAINFLAG
void *ptr = node_to_buffer(obj); void *ptr = node_to_buffer(obj);
@ -75,7 +75,7 @@ allocate(size_t size, TypeHandle type_handle) {
obj = (ObjectNode *)(aligned - flag_reserved_bytes); obj = (ObjectNode *)(aligned - flag_reserved_bytes);
#ifdef USE_DELETEDCHAINFLAG #ifdef USE_DELETEDCHAINFLAG
obj->_flag = DCF_alive; obj->_flag.store(DCF_alive, std::memory_order_relaxed);
#endif // USE_DELETEDCHAINFLAG #endif // USE_DELETEDCHAINFLAG
void *ptr = node_to_buffer(obj); void *ptr = node_to_buffer(obj);
@ -116,14 +116,16 @@ deallocate(void *ptr, TypeHandle type_handle) {
ObjectNode *obj = buffer_to_node(ptr); ObjectNode *obj = buffer_to_node(ptr);
#ifdef USE_DELETEDCHAINFLAG #ifdef USE_DELETEDCHAINFLAG
AtomicAdjust::Integer orig_flag = AtomicAdjust::compare_and_exchange(obj->_flag, DCF_alive, DCF_deleted); DeletedChainFlag orig_flag = DCF_alive;
if (UNLIKELY(!obj->_flag.compare_exchange_strong(orig_flag, DCF_deleted,
std::memory_order_relaxed))) {
// If this assertion is triggered, you double-deleted an object. // If this assertion is triggered, you double-deleted an object.
assert(orig_flag != (AtomicAdjust::Integer)DCF_deleted); assert(orig_flag != DCF_deleted);
// If this assertion is triggered, you tried to delete an object that was // If this assertion is triggered, you tried to delete an object that was
// never allocated, or you have heap corruption. // never allocated, or you have heap corruption.
assert(orig_flag == (AtomicAdjust::Integer)DCF_alive); assert(orig_flag == DCF_alive);
}
#endif // USE_DELETEDCHAINFLAG #endif // USE_DELETEDCHAINFLAG
_lock.lock(); _lock.lock();

View File

@ -20,6 +20,7 @@
#include "atomicAdjust.h" #include "atomicAdjust.h"
#include "numeric_types.h" #include "numeric_types.h"
#include "typeHandle.h" #include "typeHandle.h"
#include "patomic.h"
#include <assert.h> #include <assert.h>
// Though it's tempting, it doesn't seem to be possible to implement // Though it's tempting, it doesn't seem to be possible to implement
@ -37,7 +38,7 @@
#endif // NDEBUG #endif // NDEBUG
#ifdef USE_DELETEDCHAINFLAG #ifdef USE_DELETEDCHAINFLAG
enum DeletedChainFlag { enum DeletedChainFlag : unsigned int {
DCF_deleted = 0xfeedba0f, DCF_deleted = 0xfeedba0f,
DCF_alive = 0x12487654, DCF_alive = 0x12487654,
}; };
@ -73,7 +74,7 @@ private:
// In development mode, we piggyback this extra data. This is maintained // In development mode, we piggyback this extra data. This is maintained
// out-of-band from the actual pointer returned, so we can safely use this // out-of-band from the actual pointer returned, so we can safely use this
// flag to indicate the difference between allocated and freed pointers. // flag to indicate the difference between allocated and freed pointers.
TVOLATILE AtomicAdjust::Integer _flag; patomic<DeletedChainFlag> _flag;
#endif #endif
// This pointer sits within the buffer, in the same space referenced by // This pointer sits within the buffer, in the same space referenced by