JD2022-TU1/main/unittests/core/system/Atomic.cpp

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);
}
}