00001 /************************************************************************************ 00002 00003 Filename : OVR_RefCount.cpp 00004 Content : Reference counting implementation 00005 Created : September 19, 2012 00006 Notes : 00007 00008 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 00009 00010 Use of this software is subject to the terms of the Oculus license 00011 agreement provided at the time of installation or download, or which 00012 otherwise accompanies this software in either electronic or hard copy form. 00013 00014 ************************************************************************************/ 00015 00016 #include "OVR_RefCount.h" 00017 #include "OVR_Atomic.h" 00018 #include "OVR_Log.h" 00019 00020 namespace OVR { 00021 00022 #ifdef OVR_CC_ARM 00023 void* ReturnArg0(void* p) 00024 { 00025 return p; 00026 } 00027 #endif 00028 00029 // ***** Reference Count Base implementation 00030 00031 RefCountImplCore::~RefCountImplCore() 00032 { 00033 // RefCount can be either 1 or 0 here. 00034 // 0 if Release() was properly called. 00035 // 1 if the object was declared on stack or as an aggregate. 00036 OVR_ASSERT(RefCount <= 1); 00037 } 00038 00039 #ifdef OVR_BUILD_DEBUG 00040 void RefCountImplCore::reportInvalidDelete(void *pmem) 00041 { 00042 OVR_DEBUG_LOG( 00043 ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); 00044 OVR_ASSERT(0); 00045 } 00046 #endif 00047 00048 RefCountNTSImplCore::~RefCountNTSImplCore() 00049 { 00050 // RefCount can be either 1 or 0 here. 00051 // 0 if Release() was properly called. 00052 // 1 if the object was declared on stack or as an aggregate. 00053 OVR_ASSERT(RefCount <= 1); 00054 } 00055 00056 #ifdef OVR_BUILD_DEBUG 00057 void RefCountNTSImplCore::reportInvalidDelete(void *pmem) 00058 { 00059 OVR_DEBUG_LOG( 00060 ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); 00061 OVR_ASSERT(0); 00062 } 00063 #endif 00064 00065 00066 // *** Thread-Safe RefCountImpl 00067 00068 void RefCountImpl::AddRef() 00069 { 00070 AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1); 00071 } 00072 void RefCountImpl::Release() 00073 { 00074 if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) 00075 delete this; 00076 } 00077 00078 // *** Thread-Safe RefCountVImpl w/virtual AddRef/Release 00079 00080 void RefCountVImpl::AddRef() 00081 { 00082 AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, 1); 00083 } 00084 void RefCountVImpl::Release() 00085 { 00086 if ((AtomicOps<int>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) 00087 delete this; 00088 } 00089 00090 // *** NON-Thread-Safe RefCountImpl 00091 00092 void RefCountNTSImpl::Release() const 00093 { 00094 RefCount--; 00095 if (RefCount == 0) 00096 delete this; 00097 } 00098 00099 00100 } // OVR