blender/intern/atomic/tests/atomic_test.cc
Campbell Barton bcb7b119ae Cleanup: remove workarounds and version checks for unsupported compilers
Match minimum supported versions from the WIKI [0] by raising them to:

- GCC 9.3.1
- CLANG 8.0
- MVCS 2019 (16.9.16 / 1928)

Details:

- Add CMake checks that ensure supported compiler versions early on.
- Previously GCC per-processor version checks served to exclude
  `__clang__`, in some cases this has been replaced by explicitly
  excluding `__clang__`. This was needed as CLANG treated some of these
  flags differently to GCC, causing the build to fail.
- Remove USE_APPLE_OMP_FIX GCC-4.2 OpenMP workaround.
- Remove linking error workaround for old MSVC versions.

[0]: https://wiki.blender.org/wiki/Building_Blender

Reviewed by: brecht, LazyDodo

Ref D16068
2022-09-27 07:05:13 +10:00

1105 lines
24 KiB
C++

/* Apache License, Version 2.0 */
#include <limits>
#include "atomic_ops.h"
#include "testing/testing.h"
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wsign-conversion"
#endif
/* -------------------------------------------------------------------- */
/** \name 64 bit unsigned int atomics
* \{ */
TEST(atomic, atomic_add_and_fetch_uint64)
{
{
uint64_t value = 1;
EXPECT_EQ(atomic_add_and_fetch_uint64(&value, 2), 3);
EXPECT_EQ(value, 3);
}
{
uint64_t value = 0x1020304050607080;
EXPECT_EQ(atomic_add_and_fetch_uint64(&value, 0x0807060504030201), 0x1827364554637281);
EXPECT_EQ(value, 0x1827364554637281);
}
{
uint64_t value = 0x9020304050607080;
EXPECT_EQ(atomic_add_and_fetch_uint64(&value, 0x0807060504030201), 0x9827364554637281);
EXPECT_EQ(value, 0x9827364554637281);
}
}
TEST(atomic, atomic_sub_and_fetch_uint64)
{
{
uint64_t value = 3;
EXPECT_EQ(atomic_sub_and_fetch_uint64(&value, 2), 1);
EXPECT_EQ(value, 1);
}
{
uint64_t value = 0x1827364554637281;
EXPECT_EQ(atomic_sub_and_fetch_uint64(&value, 0x0807060504030201), 0x1020304050607080);
EXPECT_EQ(value, 0x1020304050607080);
}
{
uint64_t value = 0x9827364554637281;
EXPECT_EQ(atomic_sub_and_fetch_uint64(&value, 0x0807060504030201), 0x9020304050607080);
EXPECT_EQ(value, 0x9020304050607080);
}
{
uint64_t value = 1;
EXPECT_EQ(atomic_sub_and_fetch_uint64(&value, 2), 0xffffffffffffffff);
EXPECT_EQ(value, 0xffffffffffffffff);
}
}
TEST(atomic, atomic_fetch_and_add_uint64)
{
{
uint64_t value = 1;
EXPECT_EQ(atomic_fetch_and_add_uint64(&value, 2), 1);
EXPECT_EQ(value, 3);
}
{
uint64_t value = 0x1020304050607080;
EXPECT_EQ(atomic_fetch_and_add_uint64(&value, 0x0807060504030201), 0x1020304050607080);
EXPECT_EQ(value, 0x1827364554637281);
}
{
uint64_t value = 0x9020304050607080;
EXPECT_EQ(atomic_fetch_and_add_uint64(&value, 0x0807060504030201), 0x9020304050607080);
EXPECT_EQ(value, 0x9827364554637281);
}
}
TEST(atomic, atomic_fetch_and_sub_uint64)
{
{
uint64_t value = 3;
EXPECT_EQ(atomic_fetch_and_sub_uint64(&value, 2), 3);
EXPECT_EQ(value, 1);
}
{
uint64_t value = 0x1827364554637281;
EXPECT_EQ(atomic_fetch_and_sub_uint64(&value, 0x0807060504030201), 0x1827364554637281);
EXPECT_EQ(value, 0x1020304050607080);
}
{
uint64_t value = 0x9827364554637281;
EXPECT_EQ(atomic_fetch_and_sub_uint64(&value, 0x0807060504030201), 0x9827364554637281);
EXPECT_EQ(value, 0x9020304050607080);
}
{
uint64_t value = 1;
EXPECT_EQ(atomic_fetch_and_sub_uint64(&value, 2), 1);
EXPECT_EQ(value, 0xffffffffffffffff);
}
}
TEST(atomic, atomic_cas_uint64)
{
{
uint64_t value = 1;
EXPECT_EQ(atomic_cas_uint64(&value, 1, 2), 1);
EXPECT_EQ(value, 2);
}
{
uint64_t value = 1;
EXPECT_EQ(atomic_cas_uint64(&value, 2, 3), 1);
EXPECT_EQ(value, 1);
}
{
uint64_t value = 0x1234567890abcdef;
EXPECT_EQ(atomic_cas_uint64(&value, 0x1234567890abcdef, 0xfedcba0987654321),
0x1234567890abcdef);
EXPECT_EQ(value, 0xfedcba0987654321);
}
{
uint64_t value = 0x1234567890abcdef;
EXPECT_EQ(atomic_cas_uint64(&value, 0xdeadbeefefefefef, 0xfedcba0987654321),
0x1234567890abcdef);
EXPECT_EQ(value, 0x1234567890abcdef);
}
}
TEST(atomic, atomic_load_uint64)
{
/* Make sure alias is implemented. */
{
uint64_t value = 2;
EXPECT_EQ(atomic_load_uint64(&value), 2);
}
/* Make sure alias is using proper bitness. */
{
const uint64_t uint64_t_max = std::numeric_limits<uint64_t>::max();
uint64_t value = uint64_t_max;
EXPECT_EQ(atomic_load_uint64(&value), uint64_t_max);
}
}
TEST(atomic, atomic_store_uint64)
{
/* Make sure alias is implemented. */
{
uint64_t value = 0;
atomic_store_uint64(&value, 2);
EXPECT_EQ(value, 2);
}
/* Make sure alias is using proper bitness. */
{
const uint64_t uint64_t_max = std::numeric_limits<uint64_t>::max();
uint64_t value = 0;
atomic_store_uint64(&value, uint64_t_max);
EXPECT_EQ(value, uint64_t_max);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name 64 bit signed int atomics
* \{ */
TEST(atomic, atomic_add_and_fetch_int64)
{
{
int64_t value = 1;
EXPECT_EQ(atomic_add_and_fetch_int64(&value, 2), 3);
EXPECT_EQ(value, 3);
}
{
int64_t value = 0x1020304050607080;
EXPECT_EQ(atomic_add_and_fetch_int64(&value, 0x0807060504030201), 0x1827364554637281);
EXPECT_EQ(value, 0x1827364554637281);
}
{
int64_t value = -0x1020304050607080;
EXPECT_EQ(atomic_add_and_fetch_int64(&value, -0x0807060504030201), -0x1827364554637281);
EXPECT_EQ(value, -0x1827364554637281);
}
}
TEST(atomic, atomic_sub_and_fetch_int64)
{
{
int64_t value = 3;
EXPECT_EQ(atomic_sub_and_fetch_int64(&value, 2), 1);
EXPECT_EQ(value, 1);
}
{
int64_t value = 0x1827364554637281;
EXPECT_EQ(atomic_sub_and_fetch_int64(&value, 0x0807060504030201), 0x1020304050607080);
EXPECT_EQ(value, 0x1020304050607080);
}
{
int64_t value = -0x1827364554637281;
EXPECT_EQ(atomic_sub_and_fetch_int64(&value, -0x0807060504030201), -0x1020304050607080);
EXPECT_EQ(value, -0x1020304050607080);
}
{
int64_t value = 1;
EXPECT_EQ(atomic_sub_and_fetch_int64(&value, 2), -1);
EXPECT_EQ(value, -1);
}
}
TEST(atomic, atomic_fetch_and_add_int64)
{
{
int64_t value = 1;
EXPECT_EQ(atomic_fetch_and_add_int64(&value, 2), 1);
EXPECT_EQ(value, 3);
}
{
int64_t value = 0x1020304050607080;
EXPECT_EQ(atomic_fetch_and_add_int64(&value, 0x0807060504030201), 0x1020304050607080);
EXPECT_EQ(value, 0x1827364554637281);
}
{
int64_t value = -0x1020304050607080;
EXPECT_EQ(atomic_fetch_and_add_int64(&value, -0x0807060504030201), -0x1020304050607080);
EXPECT_EQ(value, -0x1827364554637281);
}
}
TEST(atomic, atomic_fetch_and_sub_int64)
{
{
int64_t value = 3;
EXPECT_EQ(atomic_fetch_and_sub_int64(&value, 2), 3);
EXPECT_EQ(value, 1);
}
{
int64_t value = 0x1827364554637281;
EXPECT_EQ(atomic_fetch_and_sub_int64(&value, 0x0807060504030201), 0x1827364554637281);
EXPECT_EQ(value, 0x1020304050607080);
}
{
int64_t value = -0x1827364554637281;
EXPECT_EQ(atomic_fetch_and_sub_int64(&value, -0x0807060504030201), -0x1827364554637281);
EXPECT_EQ(value, -0x1020304050607080);
}
{
int64_t value = 1;
EXPECT_EQ(atomic_fetch_and_sub_int64(&value, 2), 1);
EXPECT_EQ(value, -1);
}
}
TEST(atomic, atomic_cas_int64)
{
{
int64_t value = 1;
EXPECT_EQ(atomic_cas_int64(&value, 1, 2), 1);
EXPECT_EQ(value, 2);
}
{
int64_t value = 1;
EXPECT_EQ(atomic_cas_int64(&value, 2, 3), 1);
EXPECT_EQ(value, 1);
}
// 0xfedcba0987654321 is -0x012345f6789abcdf
// 0xdeadbeefefefefef is -0x2152411010101011
{
int64_t value = 0x1234567890abcdef;
EXPECT_EQ(atomic_cas_int64(&value, 0x1234567890abcdef, -0x012345f6789abcdf),
0x1234567890abcdef);
EXPECT_EQ(value, -0x012345f6789abcdf);
}
{
int64_t value = 0x1234567890abcdef;
EXPECT_EQ(atomic_cas_int64(&value, 0x2152411010101011, -0x012345f6789abcdf),
0x1234567890abcdef);
EXPECT_EQ(value, 0x1234567890abcdef);
}
}
TEST(atomic, atomic_load_int64)
{
/* Make sure alias is implemented. */
{
int64_t value = 2;
EXPECT_EQ(atomic_load_int64(&value), 2);
}
/* Make sure alias is using proper bitness. */
{
const int64_t int64_t_max = std::numeric_limits<int64_t>::max();
int64_t value = int64_t_max;
EXPECT_EQ(atomic_load_int64(&value), int64_t_max);
}
}
TEST(atomic, atomic_store_int64)
{
/* Make sure alias is implemented. */
{
int64_t value = 0;
atomic_store_int64(&value, 2);
EXPECT_EQ(value, 2);
}
/* Make sure alias is using proper bitness. */
{
const int64_t int64_t_max = std::numeric_limits<int64_t>::max();
int64_t value = 0;
atomic_store_int64(&value, int64_t_max);
EXPECT_EQ(value, int64_t_max);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name 32 bit unsigned int atomics
* \{ */
TEST(atomic, atomic_add_and_fetch_uint32)
{
{
uint32_t value = 1;
EXPECT_EQ(atomic_add_and_fetch_uint32(&value, 2), 3);
EXPECT_EQ(value, 3);
}
{
uint32_t value = 0x10203040;
EXPECT_EQ(atomic_add_and_fetch_uint32(&value, 0x04030201), 0x14233241);
EXPECT_EQ(value, 0x14233241);
}
{
uint32_t value = 0x90203040;
EXPECT_EQ(atomic_add_and_fetch_uint32(&value, 0x04030201), 0x94233241);
EXPECT_EQ(value, 0x94233241);
}
}
TEST(atomic, atomic_sub_and_fetch_uint32)
{
{
uint32_t value = 3;
EXPECT_EQ(atomic_sub_and_fetch_uint32(&value, 2), 1);
EXPECT_EQ(value, 1);
}
{
uint32_t value = 0x14233241;
EXPECT_EQ(atomic_sub_and_fetch_uint32(&value, 0x04030201), 0x10203040);
EXPECT_EQ(value, 0x10203040);
}
{
uint32_t value = 0x94233241;
EXPECT_EQ(atomic_sub_and_fetch_uint32(&value, 0x04030201), 0x90203040);
EXPECT_EQ(value, 0x90203040);
}
{
uint32_t value = 1;
EXPECT_EQ(atomic_sub_and_fetch_uint32(&value, 2), 0xffffffff);
EXPECT_EQ(value, 0xffffffff);
}
}
TEST(atomic, atomic_cas_uint32)
{
{
uint32_t value = 1;
EXPECT_EQ(atomic_cas_uint32(&value, 1, 2), 1);
EXPECT_EQ(value, 2);
}
{
uint32_t value = 1;
EXPECT_EQ(atomic_cas_uint32(&value, 2, 3), 1);
EXPECT_EQ(value, 1);
}
{
uint32_t value = 0x12345678;
EXPECT_EQ(atomic_cas_uint32(&value, 0x12345678, 0x87654321), 0x12345678);
EXPECT_EQ(value, 0x87654321);
}
{
uint32_t value = 0x12345678;
EXPECT_EQ(atomic_cas_uint32(&value, 0xdeadbeef, 0x87654321), 0x12345678);
EXPECT_EQ(value, 0x12345678);
}
}
TEST(atomic, atomic_load_uint32)
{
/* Make sure alias is implemented. */
{
uint32_t value = 2;
EXPECT_EQ(atomic_load_uint32(&value), 2);
}
/* Make sure alias is using proper bitness. */
{
const uint32_t uint32_t_max = std::numeric_limits<uint32_t>::max();
uint32_t value = uint32_t_max;
EXPECT_EQ(atomic_load_uint32(&value), uint32_t_max);
}
}
TEST(atomic, atomic_store_uint32)
{
/* Make sure alias is implemented. */
{
uint32_t value = 0;
atomic_store_uint32(&value, 2);
EXPECT_EQ(value, 2);
}
/* Make sure alias is using proper bitness. */
{
const uint32_t uint32_t_max = std::numeric_limits<uint32_t>::max();
uint32_t value = 0;
atomic_store_uint32(&value, uint32_t_max);
EXPECT_EQ(value, uint32_t_max);
}
}
TEST(atomic, atomic_fetch_and_add_uint32)
{
{
uint32_t value = 1;
EXPECT_EQ(atomic_fetch_and_add_uint32(&value, 2), 1);
EXPECT_EQ(value, 3);
}
{
uint32_t value = 0x10203040;
EXPECT_EQ(atomic_fetch_and_add_uint32(&value, 0x04030201), 0x10203040);
EXPECT_EQ(value, 0x14233241);
}
{
uint32_t value = 0x90203040;
EXPECT_EQ(atomic_fetch_and_add_uint32(&value, 0x04030201), 0x90203040);
EXPECT_EQ(value, 0x94233241);
}
}
TEST(atomic, atomic_fetch_and_or_uint32)
{
{
uint32_t value = 12;
EXPECT_EQ(atomic_fetch_and_or_uint32(&value, 5), 12);
EXPECT_EQ(value, 13);
}
{
uint32_t value = 0x12345678;
EXPECT_EQ(atomic_fetch_and_or_uint32(&value, 0x87654321), 0x12345678);
EXPECT_EQ(value, 0x97755779);
}
{
uint32_t value = 0x92345678;
EXPECT_EQ(atomic_fetch_and_or_uint32(&value, 0x87654321), 0x92345678);
EXPECT_EQ(value, 0x97755779);
}
}
TEST(atomic, atomic_fetch_and_and_uint32)
{
{
uint32_t value = 12;
EXPECT_EQ(atomic_fetch_and_and_uint32(&value, 5), 12);
EXPECT_EQ(value, 4);
}
{
uint32_t value = 0x12345678;
EXPECT_EQ(atomic_fetch_and_and_uint32(&value, 0x87654321), 0x12345678);
EXPECT_EQ(value, 0x02244220);
}
{
uint32_t value = 0x92345678;
EXPECT_EQ(atomic_fetch_and_and_uint32(&value, 0x87654321), 0x92345678);
EXPECT_EQ(value, 0x82244220);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name 32 bit signed int atomics
* \{ */
TEST(atomic, atomic_add_and_fetch_int32)
{
{
int32_t value = 1;
EXPECT_EQ(atomic_add_and_fetch_int32(&value, 2), 3);
EXPECT_EQ(value, 3);
}
{
int32_t value = 0x10203040;
EXPECT_EQ(atomic_add_and_fetch_int32(&value, 0x04030201), 0x14233241);
EXPECT_EQ(value, 0x14233241);
}
{
int32_t value = -0x10203040;
EXPECT_EQ(atomic_add_and_fetch_int32(&value, -0x04030201), -0x14233241);
EXPECT_EQ(value, -0x14233241);
}
}
TEST(atomic, atomic_sub_and_fetch_int32)
{
{
int32_t value = 3;
EXPECT_EQ(atomic_sub_and_fetch_int32(&value, 2), 1);
EXPECT_EQ(value, 1);
}
{
int32_t value = 0x14233241;
EXPECT_EQ(atomic_sub_and_fetch_int32(&value, 0x04030201), 0x10203040);
EXPECT_EQ(value, 0x10203040);
}
{
int32_t value = -0x14233241;
EXPECT_EQ(atomic_sub_and_fetch_int32(&value, -0x04030201), -0x10203040);
EXPECT_EQ(value, -0x10203040);
}
{
int32_t value = 1;
EXPECT_EQ(atomic_sub_and_fetch_int32(&value, 2), 0xffffffff);
EXPECT_EQ(value, 0xffffffff);
}
}
TEST(atomic, atomic_cas_int32)
{
{
int32_t value = 1;
EXPECT_EQ(atomic_cas_int32(&value, 1, 2), 1);
EXPECT_EQ(value, 2);
}
{
int32_t value = 1;
EXPECT_EQ(atomic_cas_int32(&value, 2, 3), 1);
EXPECT_EQ(value, 1);
}
// 0x87654321 is -0x789abcdf
// 0xdeadbeef is -0x21524111
{
int32_t value = 0x12345678;
EXPECT_EQ(atomic_cas_int32(&value, 0x12345678, -0x789abcdf), 0x12345678);
EXPECT_EQ(value, -0x789abcdf);
}
{
int32_t value = 0x12345678;
EXPECT_EQ(atomic_cas_int32(&value, -0x21524111, -0x789abcdf), 0x12345678);
EXPECT_EQ(value, 0x12345678);
}
}
TEST(atomic, atomic_load_int32)
{
/* Make sure alias is implemented. */
{
int32_t value = 2;
EXPECT_EQ(atomic_load_int32(&value), 2);
}
/* Make sure alias is using proper bitness. */
{
const int32_t int32_t_max = std::numeric_limits<int32_t>::max();
int32_t value = int32_t_max;
EXPECT_EQ(atomic_load_int32(&value), int32_t_max);
}
}
TEST(atomic, atomic_store_int32)
{
/* Make sure alias is implemented. */
{
int32_t value = 0;
atomic_store_int32(&value, 2);
EXPECT_EQ(value, 2);
}
/* Make sure alias is using proper bitness. */
{
const int32_t int32_t_max = std::numeric_limits<int32_t>::max();
int32_t value = 0;
atomic_store_int32(&value, int32_t_max);
EXPECT_EQ(value, int32_t_max);
}
}
TEST(atomic, atomic_fetch_and_add_int32)
{
{
int32_t value = 1;
EXPECT_EQ(atomic_fetch_and_add_int32(&value, 2), 1);
EXPECT_EQ(value, 3);
}
{
int32_t value = 0x10203040;
EXPECT_EQ(atomic_fetch_and_add_int32(&value, 0x04030201), 0x10203040);
EXPECT_EQ(value, 0x14233241);
}
{
int32_t value = -0x10203040;
EXPECT_EQ(atomic_fetch_and_add_int32(&value, -0x04030201), -0x10203040);
EXPECT_EQ(value, -0x14233241);
}
}
TEST(atomic, atomic_fetch_and_or_int32)
{
{
int32_t value = 12;
EXPECT_EQ(atomic_fetch_and_or_int32(&value, 5), 12);
EXPECT_EQ(value, 13);
}
// 0x87654321 is -0x789abcdf
{
int32_t value = 0x12345678;
EXPECT_EQ(atomic_fetch_and_or_int32(&value, -0x789abcdf), 0x12345678);
EXPECT_EQ(value, 0x97755779);
}
}
TEST(atomic, atomic_fetch_and_and_int32)
{
{
int32_t value = 12;
EXPECT_EQ(atomic_fetch_and_and_int32(&value, 5), 12);
EXPECT_EQ(value, 4);
}
{
int32_t value = 0x12345678;
EXPECT_EQ(atomic_fetch_and_and_int32(&value, -0x789abcdf), 0x12345678);
EXPECT_EQ(value, 0x02244220);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name 16 bit signed int atomics
* \{ */
TEST(atomic, atomic_fetch_and_or_int16)
{
{
int16_t value = 12;
EXPECT_EQ(atomic_fetch_and_or_int16(&value, 5), 12);
EXPECT_EQ(value, 13);
}
{
int16_t value = 0x1234;
EXPECT_EQ(atomic_fetch_and_or_int16(&value, -0x5678), 0x1234);
EXPECT_EQ(value, -0x4444);
}
}
TEST(atomic, atomic_fetch_and_and_int16)
{
{
int16_t value = 12;
EXPECT_EQ(atomic_fetch_and_and_int16(&value, 5), 12);
EXPECT_EQ(value, 4);
}
{
int16_t value = 0x1234;
EXPECT_EQ(atomic_fetch_and_and_int16(&value, -0x789A), 0x1234);
EXPECT_EQ(value, 0x224);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name 8 bit unsigned int atomics
* \{ */
TEST(atomic, atomic_fetch_and_or_uint8)
{
{
uint8_t value = 12;
EXPECT_EQ(atomic_fetch_and_or_uint8(&value, 5), 12);
EXPECT_EQ(value, 13);
}
}
TEST(atomic, atomic_fetch_and_and_uint8)
{
{
uint8_t value = 12;
EXPECT_EQ(atomic_fetch_and_and_uint8(&value, 5), 12);
EXPECT_EQ(value, 4);
}
}
/** \} */
/** \name 8 bit signed int atomics
* \{ */
TEST(atomic, atomic_fetch_and_or_int8)
{
{
int8_t value = 12;
EXPECT_EQ(atomic_fetch_and_or_int8(&value, 5), 12);
EXPECT_EQ(value, 13);
}
}
TEST(atomic, atomic_fetch_and_and_int8)
{
{
int8_t value = 12;
EXPECT_EQ(atomic_fetch_and_and_int8(&value, 5), 12);
EXPECT_EQ(value, 4);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name char aliases
* \{ */
TEST(atomic, atomic_fetch_and_or_char)
{
{
char value = 12;
EXPECT_EQ(atomic_fetch_and_or_char(&value, 5), 12);
EXPECT_EQ(value, 13);
}
}
TEST(atomic, atomic_fetch_and_and_char)
{
{
char value = 12;
EXPECT_EQ(atomic_fetch_and_and_char(&value, 5), 12);
EXPECT_EQ(value, 4);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name size_t aliases
* \{ */
TEST(atomic, atomic_add_and_fetch_z)
{
/* Make sure alias is implemented. */
{
size_t value = 1;
EXPECT_EQ(atomic_add_and_fetch_z(&value, 2), 3);
EXPECT_EQ(value, 3);
}
/* Make sure alias is using proper bitness. */
{
const size_t size_t_max = std::numeric_limits<size_t>::max();
size_t value = size_t_max - 10;
EXPECT_EQ(atomic_add_and_fetch_z(&value, 2), size_t_max - 8);
EXPECT_EQ(value, size_t_max - 8);
}
}
TEST(atomic, atomic_sub_and_fetch_z)
{
/* Make sure alias is implemented. */
{
size_t value = 3;
EXPECT_EQ(atomic_sub_and_fetch_z(&value, 2), 1);
EXPECT_EQ(value, 1);
}
/* Make sure alias is using proper bitness. */
{
const size_t size_t_max = std::numeric_limits<size_t>::max();
size_t value = size_t_max - 10;
EXPECT_EQ(atomic_sub_and_fetch_z(&value, 2), size_t_max - 12);
EXPECT_EQ(value, size_t_max - 12);
}
}
TEST(atomic, atomic_fetch_and_add_z)
{
/* Make sure alias is implemented. */
{
size_t value = 1;
EXPECT_EQ(atomic_fetch_and_add_z(&value, 2), 1);
EXPECT_EQ(value, 3);
}
/* Make sure alias is using proper bitness. */
{
const size_t size_t_max = std::numeric_limits<size_t>::max();
size_t value = size_t_max - 10;
EXPECT_EQ(atomic_fetch_and_add_z(&value, 2), size_t_max - 10);
EXPECT_EQ(value, size_t_max - 8);
}
}
TEST(atomic, atomic_fetch_and_sub_z)
{
/* Make sure alias is implemented. */
{
size_t value = 3;
EXPECT_EQ(atomic_fetch_and_sub_z(&value, 2), 3);
EXPECT_EQ(value, 1);
}
/* Make sure alias is using proper bitness. */
{
const size_t size_t_max = std::numeric_limits<size_t>::max();
size_t value = size_t_max - 10;
EXPECT_EQ(atomic_fetch_and_sub_z(&value, 2), size_t_max - 10);
EXPECT_EQ(value, size_t_max - 12);
}
}
TEST(atomic, atomic_cas_z)
{
/* Make sure alias is implemented. */
{
size_t value = 1;
EXPECT_EQ(atomic_cas_z(&value, 1, 2), 1);
EXPECT_EQ(value, 2);
}
/* Make sure alias is using proper bitness. */
{
const size_t size_t_max = std::numeric_limits<size_t>::max();
size_t value = 1;
EXPECT_EQ(atomic_cas_z(&value, 1, size_t_max), 1);
EXPECT_EQ(value, size_t_max);
}
}
TEST(atomic, atomic_load_z)
{
/* Make sure alias is implemented. */
{
size_t value = 2;
EXPECT_EQ(atomic_load_z(&value), 2);
}
/* Make sure alias is using proper bitness. */
{
const size_t size_t_max = std::numeric_limits<size_t>::max();
size_t value = size_t_max;
EXPECT_EQ(atomic_load_z(&value), size_t_max);
}
}
TEST(atomic, atomic_store_z)
{
/* Make sure alias is implemented. */
{
size_t value = 0;
atomic_store_z(&value, 2);
EXPECT_EQ(value, 2);
}
/* Make sure alias is using proper bitness. */
{
const size_t size_t_max = std::numeric_limits<size_t>::max();
size_t value = 0;
atomic_store_z(&value, size_t_max);
EXPECT_EQ(value, size_t_max);
}
}
TEST(atomic, atomic_fetch_and_update_max_z)
{
const size_t size_t_max = std::numeric_limits<size_t>::max();
size_t value = 12;
EXPECT_EQ(atomic_fetch_and_update_max_z(&value, 8), 12);
EXPECT_EQ(value, 12);
EXPECT_EQ(atomic_fetch_and_update_max_z(&value, 24), 12);
EXPECT_EQ(value, 24);
EXPECT_EQ(atomic_fetch_and_update_max_z(&value, size_t_max), 24);
EXPECT_EQ(value, size_t_max);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name unsigned int aliases
* \{ */
TEST(atomic, atomic_add_and_fetch_u)
{
/* Make sure alias is implemented. */
{
unsigned int value = 1;
EXPECT_EQ(atomic_add_and_fetch_u(&value, 2), 3);
EXPECT_EQ(value, 3);
}
/* Make sure alias is using proper bitness. */
{
const unsigned int uint_max = std::numeric_limits<unsigned int>::max();
unsigned int value = uint_max - 10;
EXPECT_EQ(atomic_add_and_fetch_u(&value, 2), uint_max - 8);
EXPECT_EQ(value, uint_max - 8);
}
}
TEST(atomic, atomic_sub_and_fetch_u)
{
/* Make sure alias is implemented. */
{
unsigned int value = 3;
EXPECT_EQ(atomic_sub_and_fetch_u(&value, 2), 1);
EXPECT_EQ(value, 1);
}
/* Make sure alias is using proper bitness. */
{
const unsigned int uint_max = std::numeric_limits<unsigned int>::max();
unsigned int value = uint_max - 10;
EXPECT_EQ(atomic_sub_and_fetch_u(&value, 2), uint_max - 12);
EXPECT_EQ(value, uint_max - 12);
}
}
TEST(atomic, atomic_fetch_and_add_u)
{
/* Make sure alias is implemented. */
{
unsigned int value = 1;
EXPECT_EQ(atomic_fetch_and_add_u(&value, 2), 1);
EXPECT_EQ(value, 3);
}
/* Make sure alias is using proper bitness. */
{
const unsigned int uint_max = std::numeric_limits<unsigned int>::max();
unsigned int value = uint_max - 10;
EXPECT_EQ(atomic_fetch_and_add_u(&value, 2), uint_max - 10);
EXPECT_EQ(value, uint_max - 8);
}
}
TEST(atomic, atomic_fetch_and_sub_u)
{
/* Make sure alias is implemented. */
{
unsigned int value = 3;
EXPECT_EQ(atomic_fetch_and_sub_u(&value, 2), 3);
EXPECT_EQ(value, 1);
}
/* Make sure alias is using proper bitness. */
{
const unsigned int uint_max = std::numeric_limits<unsigned int>::max();
unsigned int value = uint_max - 10;
EXPECT_EQ(atomic_fetch_and_sub_u(&value, 2), uint_max - 10);
EXPECT_EQ(value, uint_max - 12);
}
}
TEST(atomic, atomic_cas_u)
{
/* Make sure alias is implemented. */
{
unsigned int value = 1;
EXPECT_EQ(atomic_cas_u(&value, 1, 2), 1);
EXPECT_EQ(value, 2);
}
/* Make sure alias is using proper bitness. */
{
const unsigned int uint_max = std::numeric_limits<unsigned int>::max();
unsigned int value = 1;
EXPECT_EQ(atomic_cas_u(&value, 1, uint_max), 1);
EXPECT_EQ(value, uint_max);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name pointer aliases
* \{ */
#define INT_AS_PTR(a) reinterpret_cast<void *>((a))
TEST(atomic, atomic_cas_ptr)
{
{
void *value = INT_AS_PTR(0x7f);
EXPECT_EQ(atomic_cas_ptr(&value, INT_AS_PTR(0x7f), INT_AS_PTR(0xef)), INT_AS_PTR(0x7f));
EXPECT_EQ(value, INT_AS_PTR(0xef));
}
}
TEST(atomic, atomic_load_ptr)
{
{
void *value = INT_AS_PTR(0x7f);
void *dest = atomic_load_ptr(&value);
EXPECT_EQ(dest, INT_AS_PTR(0x7f));
}
}
TEST(atomic, atomic_store_ptr)
{
{
void *value = INT_AS_PTR(0x7f);
void *dest = nullptr;
atomic_store_ptr(&dest, value);
EXPECT_EQ(dest, INT_AS_PTR(0x7f));
}
}
#undef INT_AS_PTR
/** \} */
/* -------------------------------------------------------------------- */
/** \name floating point atomics
* \{ */
TEST(atomic, atomic_cas_float)
{
{
float value = 1.234f;
EXPECT_EQ(atomic_cas_float(&value, 1.234f, 2.71f), 1.234f);
EXPECT_EQ(value, 2.71f);
}
}
TEST(atomic, atomic_add_and_fetch_fl)
{
{
float value = 1.23f;
EXPECT_NEAR(atomic_add_and_fetch_fl(&value, 2.71f), 3.94f, 1e-8f);
EXPECT_NEAR(value, 3.94f, 1e-8f);
}
}
/** \} */