attempt to robustify

This commit is contained in:
David Rose 2007-04-03 23:20:18 +00:00
parent b39ca2fec5
commit 3010785e58
2 changed files with 63 additions and 4 deletions

View File

@ -169,6 +169,32 @@ deallocate(Type *ptr, TypeHandle type_handle) {
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE #endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
} }
////////////////////////////////////////////////////////////////////
// Function: DeletedChain::validate
// Access: Public
// Description: Returns true if the pointer is valid, false if it has
// been deleted or if it was never a valid pointer.
//
// This is only meaningful in debug mode, where
// USE_DELETEDCHAINFLAG is defined. If not, this
// trivially returns true.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE bool DeletedChain<Type>::
validate(const Type *ptr) {
TAU_PROFILE("bool DeletedChain<Type>::validate(Type *)", " ", TAU_USER);
if (ptr == (Type *)NULL) {
return false;
}
#ifdef USE_DELETEDCHAINFLAG
TVOLATILE const ObjectNode *obj = type_to_node((Type *)ptr);
return AtomicAdjust::get(obj->_flag) == DCF_alive;
#else
return true;
#endif // NDEBUG
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DeletedChain::node_to_type // Function: DeletedChain::node_to_type
// Access: Private, Static // Access: Private, Static
@ -213,7 +239,34 @@ template<class Type>
INLINE void DeletedChain<Type>:: INLINE void DeletedChain<Type>::
init_lock() { init_lock() {
if (_lock == (MutexImpl *)NULL) { if (_lock == (MutexImpl *)NULL) {
_lock = new MutexImpl; do_init_lock();
} }
} }
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE #endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
////////////////////////////////////////////////////////////////////
// Function: DeletedChain::do_init_lock
// Access: Private
// Description: Allocates the lock pointer if necessary. Makes some
// pains to protect itself from race conditions.
////////////////////////////////////////////////////////////////////
template<class Type>
void DeletedChain<Type>::
do_init_lock() {
MutexImpl *lock = new MutexImpl;
// Even though DELETED_CHAIN_USE_ATOMIC_EXCHANGE is not true, we
// will take advantage of the atomic exchange operation here, at
// startup. We have to rely on something, after all, before we have
// created the first mutex.
MutexImpl *result;
result = (MutexImpl *)AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_lock, (void *)NULL, (void *)lock);
if (result != NULL) {
delete lock;
}
assert(_lock != (MutexImpl *)NULL);
}
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE

View File

@ -39,7 +39,7 @@
#endif #endif
#ifndef NDEBUG #ifndef NDEBUG
// In development mode, we defined USE_DELETEDCHAINFLAG, which // In development mode, we define USE_DELETEDCHAINFLAG, which
// triggers the piggyback of an additional word of data on every // triggers the piggyback of an additional word of data on every
// allocated block, so we can ensure that an object is not // allocated block, so we can ensure that an object is not
// double-deleted and that the deleted chain remains intact. // double-deleted and that the deleted chain remains intact.
@ -85,6 +85,8 @@ public:
INLINE static Type *allocate(size_t size, TypeHandle type_handle); INLINE static Type *allocate(size_t size, TypeHandle type_handle);
INLINE static void deallocate(Type *ptr, TypeHandle type_handle); INLINE static void deallocate(Type *ptr, TypeHandle type_handle);
INLINE static bool validate(const Type *ptr);
private: private:
class ObjectNode { class ObjectNode {
public: public:
@ -117,6 +119,7 @@ private:
// If we don't have atomic compare-and-exchange, we need to use a // If we don't have atomic compare-and-exchange, we need to use a
// Mutex to protect the above linked list. // Mutex to protect the above linked list.
static INLINE void init_lock(); static INLINE void init_lock();
static void do_init_lock();
static MutexImpl *_lock; static MutexImpl *_lock;
#endif #endif
}; };
@ -135,6 +138,9 @@ private:
DeletedChain< Type >::deallocate((Type *)ptr, get_type_handle(Type)); \ DeletedChain< Type >::deallocate((Type *)ptr, get_type_handle(Type)); \
} \ } \
inline void operator delete(void *, void *) { \ inline void operator delete(void *, void *) { \
} \
inline static bool validate_ptr(const void *ptr) { \
return DeletedChain< Type >::validate((const Type *)ptr); \
} }
#include "deletedChain.T" #include "deletedChain.T"