150 lines
5 KiB
C++
150 lines
5 KiB
C++
#include "precompiled_unittests_core.h"
|
|
|
|
#include "core/system/Atomic.h"
|
|
|
|
|
|
namespace ITF
|
|
{
|
|
|
|
namespace
|
|
{
|
|
|
|
template<typename TheFunction1ArgType, typename TheBaseType>
|
|
void testFunction1Arg(TheFunction1ArgType _function1Arg, TheBaseType _argValue, TheBaseType _functionResult, TheBaseType _variableFinalValue)
|
|
{
|
|
volatile TheBaseType _variable = _argValue;
|
|
TheBaseType result = _function1Arg(_variable);
|
|
|
|
EXPECT_EQ(result, _functionResult);
|
|
EXPECT_EQ(_variable, _variableFinalValue);
|
|
}
|
|
|
|
|
|
template<typename TheFunction2ArgsType, typename TheBaseType>
|
|
void testFunction2Args(TheFunction2ArgsType _function2Args, TheBaseType _arg1Value, TheBaseType _arg2Value, TheBaseType _functionResult, TheBaseType _variableFinalValue)
|
|
{
|
|
volatile TheBaseType _variable = _arg1Value;
|
|
TheBaseType result = _function2Args(_variable, _arg2Value);
|
|
|
|
EXPECT_EQ(result, _functionResult);
|
|
EXPECT_EQ(_variable, _variableFinalValue);
|
|
}
|
|
|
|
|
|
template<typename TheFunction3ArgsType, typename TheBaseType>
|
|
void testFunction3Args(TheFunction3ArgsType _function3Args, TheBaseType _arg1Value, TheBaseType _arg2Value, TheBaseType _arg3Value, TheBaseType _functionResult, TheBaseType _variableFinalValue)
|
|
{
|
|
volatile TheBaseType _variable = _arg1Value;
|
|
TheBaseType result = _function3Args(_variable, _arg2Value, _arg3Value);
|
|
|
|
EXPECT_EQ(result, _functionResult);
|
|
EXPECT_EQ(_variable, _variableFinalValue);
|
|
}
|
|
|
|
|
|
template<typename TheBaseType>
|
|
void testFunctionAdd(TheBaseType _originalValue, TheBaseType _addValue)
|
|
{
|
|
TheBaseType expectedResult = _originalValue + _addValue;
|
|
testFunction2Args(Atomic::add, _originalValue, _addValue, expectedResult, expectedResult);
|
|
}
|
|
|
|
|
|
template<typename TheBaseType>
|
|
void testFunctionSub(TheBaseType _originalValue, TheBaseType _subValue)
|
|
{
|
|
TheBaseType expectedResult = _originalValue - _subValue;
|
|
testFunction2Args(Atomic::sub, _originalValue, _subValue, expectedResult, expectedResult);
|
|
}
|
|
|
|
|
|
template<typename TheBaseType>
|
|
void testFunctionIncrement(TheBaseType _originalValue)
|
|
{
|
|
typedef TheBaseType (*TheFunction1ArgType) (volatile TheBaseType&);
|
|
TheBaseType expectedResult = _originalValue + 1;
|
|
testFunction1Arg<TheFunction1ArgType, TheBaseType>(Atomic::increment, _originalValue, expectedResult, expectedResult);
|
|
}
|
|
|
|
|
|
template<typename TheBaseType>
|
|
void testFunctionDecrement(TheBaseType _originalValue)
|
|
{
|
|
typedef TheBaseType (*TheFunction1ArgType) (volatile TheBaseType&);
|
|
TheBaseType expectedResult = _originalValue - 1;
|
|
testFunction1Arg<TheFunction1ArgType, TheBaseType>(Atomic::decrement, _originalValue, expectedResult, expectedResult);
|
|
}
|
|
|
|
|
|
template<typename TheBaseType>
|
|
void testFunctionExchange(TheBaseType _originalValue, TheBaseType _newValue)
|
|
{
|
|
typedef TheBaseType (*TheFunction2ArgsType) (volatile TheBaseType&, TheBaseType);
|
|
testFunction2Args<TheFunction2ArgsType, TheBaseType>(Atomic::exchange, _originalValue, _newValue, _originalValue, _newValue);
|
|
}
|
|
|
|
|
|
template<typename TheBaseType>
|
|
void testFunctionExchangeIfEqual(TheBaseType _originalValue, TheBaseType _compareValue, TheBaseType _assignValue)
|
|
{
|
|
typedef TheBaseType (*TheFunction3ArgsType) (volatile TheBaseType&, TheBaseType, TheBaseType);
|
|
TheBaseType functionResult = _originalValue;
|
|
TheBaseType variableFinalValue = (_originalValue == _compareValue ? _assignValue : _originalValue);
|
|
testFunction3Args<TheFunction3ArgsType, TheBaseType>(Atomic::exchangeIfEqual, _originalValue, _compareValue, _assignValue, functionResult, variableFinalValue);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
TEST(Atomic, test_add)
|
|
{
|
|
testFunctionAdd<i32>(5, 8);
|
|
testFunctionAdd<i32>(17, I32_MAX);
|
|
}
|
|
|
|
|
|
TEST(Atomic, test_sub)
|
|
{
|
|
testFunctionSub<i32>(5, 8);
|
|
testFunctionSub<i32>(17, I32_MIN);
|
|
}
|
|
|
|
|
|
TEST(Atomic, test_increment)
|
|
{
|
|
testFunctionIncrement<i32>(-3);
|
|
testFunctionIncrement<i32>(5);
|
|
|
|
testFunctionIncrement<u32>(7);
|
|
testFunctionIncrement<u32>(58);
|
|
}
|
|
|
|
|
|
TEST(Atomic, test_decrement)
|
|
{
|
|
testFunctionDecrement<i32>(-3);
|
|
testFunctionDecrement<i32>(5);
|
|
|
|
testFunctionDecrement<u32>(7);
|
|
testFunctionDecrement<u32>(58);
|
|
}
|
|
|
|
|
|
TEST(Atomic, test_exchange)
|
|
{
|
|
testFunctionExchange<i32>(-5, 8);
|
|
|
|
testFunctionExchange<u32>(42, 84);
|
|
}
|
|
|
|
|
|
TEST(Atomic, test_exchangeIfEqual)
|
|
{
|
|
testFunctionExchangeIfEqual<i32>(5, 5, 1);
|
|
testFunctionExchangeIfEqual<i32>(5, 8, 1);
|
|
|
|
testFunctionExchangeIfEqual<i64>(5, 5, 1);
|
|
testFunctionExchangeIfEqual<i64>(5, 8, 1);
|
|
}
|
|
|
|
}
|