107 lines
3.8 KiB
C++
107 lines
3.8 KiB
C++
/*
|
|
Test-ZReferenceCounter.cpp
|
|
Author: James Russell <jcrussell@762studios.com>
|
|
|
|
Purpose: Unit Test the ZReferenceCounter class.
|
|
*/
|
|
|
|
#include "ZUnitTest.hpp"
|
|
|
|
#include <ZUtil/ZConcurrency.hpp>
|
|
#include <ZUtil/ZReferenceCounter.hpp>
|
|
#include <SST/SST_Thread.h> // SST_Concurrency_YieldThread()
|
|
|
|
static const char* test_GainLoseReferences();
|
|
static const char* test_Signal();
|
|
|
|
//List of unit tests
|
|
ZUnitTest ZReferenceCounterUnitTests[] =
|
|
{
|
|
{ "ZReferenceCounter: Gain / Lose References", test_GainLoseReferences },
|
|
{ "ZReferenceCounter: Signal", test_Signal }
|
|
};
|
|
|
|
//Now declare the ZUnitTestBlock associated with this.
|
|
DECLARE_ZTESTBLOCK(ZReferenceCounter);
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
static const char* test_GainLoseReferences()
|
|
{
|
|
ZReferenceCounter counter;
|
|
|
|
//Ensure both start at zero
|
|
TASSERT(counter.GetStrongRefCount() == 0, "Strong count set to non-zero value on default construct!");
|
|
TASSERT(counter.GetWeakRefCount() == 0, "Weak count set to non-zero value on default construct!");
|
|
|
|
//Test GainStrongRef()
|
|
counter.GainStrongRef();
|
|
TASSERT(counter.GetStrongRefCount() == 1, "Strong count not equal to 1 after strong reference gained!");
|
|
|
|
//Test GainWeakRef()
|
|
counter.GainWeakRef();
|
|
counter.GainWeakRef();
|
|
TASSERT(counter.GetWeakRefCount() == 2, "Weak count not equal to 2 after double increment!");
|
|
|
|
//Test validity of both counters after weak ref decrement
|
|
uint32_t combinedCount = counter.LoseWeakRef();
|
|
TASSERT(ZREFCOUNTER_EXTRACT_STRONG_REF(combinedCount) == 1, "After losing weak reference, strong count does not equal one!");
|
|
TASSERT(ZREFCOUNTER_EXTRACT_WEAK_REF(combinedCount) == 1, "After losing weak reference, weak count does not equal one!");
|
|
|
|
//Test validity of both counters after strong ref decrement
|
|
combinedCount = counter.LoseStrongRef();
|
|
TASSERT(ZREFCOUNTER_EXTRACT_STRONG_REF(combinedCount) == 0, "After losing strong reference, strong count does not equal zero!");
|
|
TASSERT(ZREFCOUNTER_EXTRACT_WEAK_REF(combinedCount) == 1, "After losing strong reference, weak count does not equal one!");
|
|
|
|
//Test validity of both counters when all references are lost
|
|
combinedCount = counter.LoseWeakRef();
|
|
TASSERT(ZREFCOUNTER_EXTRACT_STRONG_REF(combinedCount) == 0, "After losing second weak reference, strong count does not equal zero!");
|
|
TASSERT(ZREFCOUNTER_EXTRACT_WEAK_REF(combinedCount) == 0, "After losing second weak reference, weak count does not equal one!");
|
|
|
|
return ZTEST_SUCCESS;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
static int signalDeallocate(void* _refCounter)
|
|
{
|
|
//This should block
|
|
reinterpret_cast<ZReferenceCounter*>(_refCounter)->SignalDeallocateObject();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const char* test_Signal()
|
|
{
|
|
ZReferenceCounter counter;
|
|
|
|
counter.GainStrongRef();
|
|
counter.GainWeakRef();
|
|
|
|
TASSERT(counter.GetStrongRefCount() == 1, "Strong count incorrect after GainStrongRef!");
|
|
TASSERT(counter.GetWeakRefCount() == 1, "Weak count incorrect after GainWeakRef!");
|
|
|
|
TASSERT(counter.SignalInUse(), "SignalInUse returned false when it should be valid to use!");
|
|
|
|
TASSERT(counter.State > 0, "State not increased after SignalInUse!");
|
|
|
|
ZThreadContext ctxt = ZConcurrency::CreateThread(signalDeallocate, &counter);
|
|
|
|
//At this point, the other thread should be waiting on this one, but
|
|
//should signal us by setting state to NULL with an atomic XOR
|
|
while (counter.State > 0)
|
|
SST_Concurrency_YieldThread();
|
|
|
|
TASSERT(counter.SignalInUse() == false, "SignalInUse returned true when it should be invalid to use!");
|
|
|
|
counter.SignalUnused(); //This should allow the thread to return from the SignalDeallocate method
|
|
|
|
ZConcurrency::WaitThread(ctxt);
|
|
ZConcurrency::DestroyThread(ctxt);
|
|
|
|
TASSERT(counter.State == (-1 & ZREFCOUNTER_DEALLOC_BIT), "State variable invalid after SignalDeallocate and SignalUnused!");
|
|
|
|
return ZTEST_SUCCESS;
|
|
}
|