nuclear@1: /************************************************************************************ nuclear@1: nuclear@1: Filename : OVR_RefCount.cpp nuclear@1: Content : Reference counting implementation nuclear@1: Created : September 19, 2012 nuclear@1: Notes : nuclear@1: nuclear@1: Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. nuclear@1: nuclear@1: Use of this software is subject to the terms of the Oculus license nuclear@1: agreement provided at the time of installation or download, or which nuclear@1: otherwise accompanies this software in either electronic or hard copy form. nuclear@1: nuclear@1: ************************************************************************************/ nuclear@1: nuclear@1: #include "OVR_RefCount.h" nuclear@1: #include "OVR_Atomic.h" nuclear@1: #include "OVR_Log.h" nuclear@1: nuclear@1: namespace OVR { nuclear@1: nuclear@1: #ifdef OVR_CC_ARM nuclear@1: void* ReturnArg0(void* p) nuclear@1: { nuclear@1: return p; nuclear@1: } nuclear@1: #endif nuclear@1: nuclear@1: // ***** Reference Count Base implementation nuclear@1: nuclear@1: RefCountImplCore::~RefCountImplCore() nuclear@1: { nuclear@1: // RefCount can be either 1 or 0 here. nuclear@1: // 0 if Release() was properly called. nuclear@1: // 1 if the object was declared on stack or as an aggregate. nuclear@1: OVR_ASSERT(RefCount <= 1); nuclear@1: } nuclear@1: nuclear@1: #ifdef OVR_BUILD_DEBUG nuclear@1: void RefCountImplCore::reportInvalidDelete(void *pmem) nuclear@1: { nuclear@1: OVR_DEBUG_LOG( nuclear@1: ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); nuclear@1: OVR_ASSERT(0); nuclear@1: } nuclear@1: #endif nuclear@1: nuclear@1: RefCountNTSImplCore::~RefCountNTSImplCore() nuclear@1: { nuclear@1: // RefCount can be either 1 or 0 here. nuclear@1: // 0 if Release() was properly called. nuclear@1: // 1 if the object was declared on stack or as an aggregate. nuclear@1: OVR_ASSERT(RefCount <= 1); nuclear@1: } nuclear@1: nuclear@1: #ifdef OVR_BUILD_DEBUG nuclear@1: void RefCountNTSImplCore::reportInvalidDelete(void *pmem) nuclear@1: { nuclear@1: OVR_DEBUG_LOG( nuclear@1: ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); nuclear@1: OVR_ASSERT(0); nuclear@1: } nuclear@1: #endif nuclear@1: nuclear@1: nuclear@1: // *** Thread-Safe RefCountImpl nuclear@1: nuclear@1: void RefCountImpl::AddRef() nuclear@1: { nuclear@1: AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); nuclear@1: } nuclear@1: void RefCountImpl::Release() nuclear@1: { nuclear@1: if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) nuclear@1: delete this; nuclear@1: } nuclear@1: nuclear@1: // *** Thread-Safe RefCountVImpl w/virtual AddRef/Release nuclear@1: nuclear@1: void RefCountVImpl::AddRef() nuclear@1: { nuclear@1: AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); nuclear@1: } nuclear@1: void RefCountVImpl::Release() nuclear@1: { nuclear@1: if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) nuclear@1: delete this; nuclear@1: } nuclear@1: nuclear@1: // *** NON-Thread-Safe RefCountImpl nuclear@1: nuclear@1: void RefCountNTSImpl::Release() const nuclear@1: { nuclear@1: RefCount--; nuclear@1: if (RefCount == 0) nuclear@1: delete this; nuclear@1: } nuclear@1: nuclear@1: nuclear@1: } // OVR