mirror of https://github.com/postgres/postgres
Report test_atomic_ops() failures consistently, via macros.
This prints the unexpected value in more failure cases, and it removes forty-eight hand-maintained error messages. Back-patch to 9.5, which introduced these tests. Reviewed (in an earlier version) by Andres Freund. Discussion: https://postgr.es/m/20190915160021.GA24376@alvherre.pgsql
This commit is contained in:
parent
6ca51b1552
commit
57f0060891
|
@ -38,6 +38,34 @@
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define EXPECT_TRUE(expr) \
|
||||||
|
do { \
|
||||||
|
if (!(expr)) \
|
||||||
|
elog(ERROR, \
|
||||||
|
"%s was unexpectedly false in file \"%s\" line %u", \
|
||||||
|
#expr, __FILE__, __LINE__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EXPECT_EQ_U32(result_expr, expected_expr) \
|
||||||
|
do { \
|
||||||
|
uint32 result = (result_expr); \
|
||||||
|
uint32 expected = (expected_expr); \
|
||||||
|
if (result != expected) \
|
||||||
|
elog(ERROR, \
|
||||||
|
"%s yielded %u, expected %s in file \"%s\" line %u", \
|
||||||
|
#result_expr, result, #expected_expr, __FILE__, __LINE__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EXPECT_EQ_U64(result_expr, expected_expr) \
|
||||||
|
do { \
|
||||||
|
uint64 result = (result_expr); \
|
||||||
|
uint64 expected = (expected_expr); \
|
||||||
|
if (result != expected) \
|
||||||
|
elog(ERROR, \
|
||||||
|
"%s yielded " UINT64_FORMAT ", expected %s in file \"%s\" line %u", \
|
||||||
|
#result_expr, result, #expected_expr, __FILE__, __LINE__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define P_MAXDIG 12
|
#define P_MAXDIG 12
|
||||||
#define LDELIM '('
|
#define LDELIM '('
|
||||||
#define RDELIM ')'
|
#define RDELIM ')'
|
||||||
|
@ -904,27 +932,13 @@ test_atomic_flag(void)
|
||||||
pg_atomic_flag flag;
|
pg_atomic_flag flag;
|
||||||
|
|
||||||
pg_atomic_init_flag(&flag);
|
pg_atomic_init_flag(&flag);
|
||||||
|
EXPECT_TRUE(pg_atomic_unlocked_test_flag(&flag));
|
||||||
if (!pg_atomic_unlocked_test_flag(&flag))
|
EXPECT_TRUE(pg_atomic_test_set_flag(&flag));
|
||||||
elog(ERROR, "flag: unexpectedly set");
|
EXPECT_TRUE(!pg_atomic_unlocked_test_flag(&flag));
|
||||||
|
EXPECT_TRUE(!pg_atomic_test_set_flag(&flag));
|
||||||
if (!pg_atomic_test_set_flag(&flag))
|
|
||||||
elog(ERROR, "flag: couldn't set");
|
|
||||||
|
|
||||||
if (pg_atomic_unlocked_test_flag(&flag))
|
|
||||||
elog(ERROR, "flag: unexpectedly unset");
|
|
||||||
|
|
||||||
if (pg_atomic_test_set_flag(&flag))
|
|
||||||
elog(ERROR, "flag: set spuriously #2");
|
|
||||||
|
|
||||||
pg_atomic_clear_flag(&flag);
|
pg_atomic_clear_flag(&flag);
|
||||||
|
EXPECT_TRUE(pg_atomic_unlocked_test_flag(&flag));
|
||||||
if (!pg_atomic_unlocked_test_flag(&flag))
|
EXPECT_TRUE(pg_atomic_test_set_flag(&flag));
|
||||||
elog(ERROR, "flag: unexpectedly set #2");
|
|
||||||
|
|
||||||
if (!pg_atomic_test_set_flag(&flag))
|
|
||||||
elog(ERROR, "flag: couldn't set");
|
|
||||||
|
|
||||||
pg_atomic_clear_flag(&flag);
|
pg_atomic_clear_flag(&flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,75 +950,38 @@ test_atomic_uint32(void)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
pg_atomic_init_u32(&var, 0);
|
pg_atomic_init_u32(&var, 0);
|
||||||
|
EXPECT_EQ_U32(pg_atomic_read_u32(&var), 0);
|
||||||
if (pg_atomic_read_u32(&var) != 0)
|
|
||||||
elog(ERROR, "atomic_read_u32() #1 wrong");
|
|
||||||
|
|
||||||
pg_atomic_write_u32(&var, 3);
|
pg_atomic_write_u32(&var, 3);
|
||||||
|
EXPECT_EQ_U32(pg_atomic_read_u32(&var), 3);
|
||||||
if (pg_atomic_read_u32(&var) != 3)
|
EXPECT_EQ_U32(pg_atomic_fetch_add_u32(&var, pg_atomic_read_u32(&var) - 2),
|
||||||
elog(ERROR, "atomic_read_u32() #2 wrong");
|
3);
|
||||||
|
EXPECT_EQ_U32(pg_atomic_fetch_sub_u32(&var, 1), 4);
|
||||||
if (pg_atomic_fetch_add_u32(&var, pg_atomic_read_u32(&var) - 2) != 3)
|
EXPECT_EQ_U32(pg_atomic_sub_fetch_u32(&var, 3), 0);
|
||||||
elog(ERROR, "atomic_fetch_add_u32() #1 wrong");
|
EXPECT_EQ_U32(pg_atomic_add_fetch_u32(&var, 10), 10);
|
||||||
|
EXPECT_EQ_U32(pg_atomic_exchange_u32(&var, 5), 10);
|
||||||
if (pg_atomic_fetch_sub_u32(&var, 1) != 4)
|
EXPECT_EQ_U32(pg_atomic_exchange_u32(&var, 0), 5);
|
||||||
elog(ERROR, "atomic_fetch_sub_u32() #1 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_sub_fetch_u32(&var, 3) != 0)
|
|
||||||
elog(ERROR, "atomic_sub_fetch_u32() #1 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_add_fetch_u32(&var, 10) != 10)
|
|
||||||
elog(ERROR, "atomic_add_fetch_u32() #1 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_exchange_u32(&var, 5) != 10)
|
|
||||||
elog(ERROR, "pg_atomic_exchange_u32() #1 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_exchange_u32(&var, 0) != 5)
|
|
||||||
elog(ERROR, "pg_atomic_exchange_u32() #0 wrong");
|
|
||||||
|
|
||||||
/* test around numerical limits */
|
/* test around numerical limits */
|
||||||
if (pg_atomic_fetch_add_u32(&var, INT_MAX) != 0)
|
EXPECT_EQ_U32(pg_atomic_fetch_add_u32(&var, INT_MAX), 0);
|
||||||
elog(ERROR, "pg_atomic_fetch_add_u32() #2 wrong");
|
EXPECT_EQ_U32(pg_atomic_fetch_add_u32(&var, INT_MAX), INT_MAX);
|
||||||
|
|
||||||
if (pg_atomic_fetch_add_u32(&var, INT_MAX) != INT_MAX)
|
|
||||||
elog(ERROR, "pg_atomic_add_fetch_u32() #3 wrong");
|
|
||||||
|
|
||||||
pg_atomic_fetch_add_u32(&var, 2); /* wrap to 0 */
|
pg_atomic_fetch_add_u32(&var, 2); /* wrap to 0 */
|
||||||
|
EXPECT_EQ_U32(pg_atomic_fetch_add_u32(&var, PG_INT16_MAX), 0);
|
||||||
if (pg_atomic_fetch_add_u32(&var, PG_INT16_MAX) != 0)
|
EXPECT_EQ_U32(pg_atomic_fetch_add_u32(&var, PG_INT16_MAX + 1),
|
||||||
elog(ERROR, "pg_atomic_fetch_add_u32() #3 wrong");
|
PG_INT16_MAX);
|
||||||
|
EXPECT_EQ_U32(pg_atomic_fetch_add_u32(&var, PG_INT16_MIN),
|
||||||
if (pg_atomic_fetch_add_u32(&var, PG_INT16_MAX + 1) != PG_INT16_MAX)
|
2 * PG_INT16_MAX + 1);
|
||||||
elog(ERROR, "pg_atomic_fetch_add_u32() #4 wrong");
|
EXPECT_EQ_U32(pg_atomic_fetch_add_u32(&var, PG_INT16_MIN - 1),
|
||||||
|
PG_INT16_MAX);
|
||||||
if (pg_atomic_fetch_add_u32(&var, PG_INT16_MIN) != 2 * PG_INT16_MAX + 1)
|
|
||||||
elog(ERROR, "pg_atomic_fetch_add_u32() #5 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_fetch_add_u32(&var, PG_INT16_MIN - 1) != PG_INT16_MAX)
|
|
||||||
elog(ERROR, "pg_atomic_fetch_add_u32() #6 wrong");
|
|
||||||
|
|
||||||
pg_atomic_fetch_add_u32(&var, 1); /* top up to UINT_MAX */
|
pg_atomic_fetch_add_u32(&var, 1); /* top up to UINT_MAX */
|
||||||
|
EXPECT_EQ_U32(pg_atomic_read_u32(&var), UINT_MAX);
|
||||||
if (pg_atomic_read_u32(&var) != UINT_MAX)
|
EXPECT_EQ_U32(pg_atomic_fetch_sub_u32(&var, INT_MAX), UINT_MAX);
|
||||||
elog(ERROR, "atomic_read_u32() #2 wrong");
|
EXPECT_EQ_U32(pg_atomic_read_u32(&var), (uint32) INT_MAX + 1);
|
||||||
|
EXPECT_EQ_U32(pg_atomic_sub_fetch_u32(&var, INT_MAX), 1);
|
||||||
if (pg_atomic_fetch_sub_u32(&var, INT_MAX) != UINT_MAX)
|
|
||||||
elog(ERROR, "pg_atomic_fetch_sub_u32() #2 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_read_u32(&var) != (uint32) INT_MAX + 1)
|
|
||||||
elog(ERROR, "atomic_read_u32() #3 wrong: %u", pg_atomic_read_u32(&var));
|
|
||||||
|
|
||||||
expected = pg_atomic_sub_fetch_u32(&var, INT_MAX);
|
|
||||||
if (expected != 1)
|
|
||||||
elog(ERROR, "pg_atomic_sub_fetch_u32() #3 wrong: %u", expected);
|
|
||||||
|
|
||||||
pg_atomic_sub_fetch_u32(&var, 1);
|
pg_atomic_sub_fetch_u32(&var, 1);
|
||||||
|
|
||||||
/* fail exchange because of old expected */
|
/* fail exchange because of old expected */
|
||||||
expected = 10;
|
expected = 10;
|
||||||
if (pg_atomic_compare_exchange_u32(&var, &expected, 1))
|
EXPECT_TRUE(!pg_atomic_compare_exchange_u32(&var, &expected, 1));
|
||||||
elog(ERROR, "atomic_compare_exchange_u32() changed value spuriously");
|
|
||||||
|
|
||||||
/* CAS is allowed to fail due to interrupts, try a couple of times */
|
/* CAS is allowed to fail due to interrupts, try a couple of times */
|
||||||
for (i = 0; i < 1000; i++)
|
for (i = 0; i < 1000; i++)
|
||||||
|
@ -1015,31 +992,18 @@ test_atomic_uint32(void)
|
||||||
}
|
}
|
||||||
if (i == 1000)
|
if (i == 1000)
|
||||||
elog(ERROR, "atomic_compare_exchange_u32() never succeeded");
|
elog(ERROR, "atomic_compare_exchange_u32() never succeeded");
|
||||||
if (pg_atomic_read_u32(&var) != 1)
|
EXPECT_EQ_U32(pg_atomic_read_u32(&var), 1);
|
||||||
elog(ERROR, "atomic_compare_exchange_u32() didn't set value properly");
|
|
||||||
|
|
||||||
pg_atomic_write_u32(&var, 0);
|
pg_atomic_write_u32(&var, 0);
|
||||||
|
|
||||||
/* try setting flagbits */
|
/* try setting flagbits */
|
||||||
if (pg_atomic_fetch_or_u32(&var, 1) & 1)
|
EXPECT_TRUE(!(pg_atomic_fetch_or_u32(&var, 1) & 1));
|
||||||
elog(ERROR, "pg_atomic_fetch_or_u32() #1 wrong");
|
EXPECT_TRUE(pg_atomic_fetch_or_u32(&var, 2) & 1);
|
||||||
|
EXPECT_EQ_U32(pg_atomic_read_u32(&var), 3);
|
||||||
if (!(pg_atomic_fetch_or_u32(&var, 2) & 1))
|
|
||||||
elog(ERROR, "pg_atomic_fetch_or_u32() #2 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_read_u32(&var) != 3)
|
|
||||||
elog(ERROR, "invalid result after pg_atomic_fetch_or_u32()");
|
|
||||||
|
|
||||||
/* try clearing flagbits */
|
/* try clearing flagbits */
|
||||||
if ((pg_atomic_fetch_and_u32(&var, ~2) & 3) != 3)
|
EXPECT_EQ_U32(pg_atomic_fetch_and_u32(&var, ~2) & 3, 3);
|
||||||
elog(ERROR, "pg_atomic_fetch_and_u32() #1 wrong");
|
EXPECT_EQ_U32(pg_atomic_fetch_and_u32(&var, ~1), 1);
|
||||||
|
|
||||||
if (pg_atomic_fetch_and_u32(&var, ~1) != 1)
|
|
||||||
elog(ERROR, "pg_atomic_fetch_and_u32() #2 wrong: is %u",
|
|
||||||
pg_atomic_read_u32(&var));
|
|
||||||
/* no bits set anymore */
|
/* no bits set anymore */
|
||||||
if (pg_atomic_fetch_and_u32(&var, ~0) != 0)
|
EXPECT_EQ_U32(pg_atomic_fetch_and_u32(&var, ~0), 0);
|
||||||
elog(ERROR, "pg_atomic_fetch_and_u32() #3 wrong");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PG_HAVE_ATOMIC_U64_SUPPORT
|
#ifdef PG_HAVE_ATOMIC_U64_SUPPORT
|
||||||
|
@ -1051,37 +1015,20 @@ test_atomic_uint64(void)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
pg_atomic_init_u64(&var, 0);
|
pg_atomic_init_u64(&var, 0);
|
||||||
|
EXPECT_EQ_U64(pg_atomic_read_u64(&var), 0);
|
||||||
if (pg_atomic_read_u64(&var) != 0)
|
|
||||||
elog(ERROR, "atomic_read_u64() #1 wrong");
|
|
||||||
|
|
||||||
pg_atomic_write_u64(&var, 3);
|
pg_atomic_write_u64(&var, 3);
|
||||||
|
EXPECT_EQ_U64(pg_atomic_read_u64(&var), 3);
|
||||||
if (pg_atomic_read_u64(&var) != 3)
|
EXPECT_EQ_U64(pg_atomic_fetch_add_u64(&var, pg_atomic_read_u64(&var) - 2),
|
||||||
elog(ERROR, "atomic_read_u64() #2 wrong");
|
3);
|
||||||
|
EXPECT_EQ_U64(pg_atomic_fetch_sub_u64(&var, 1), 4);
|
||||||
if (pg_atomic_fetch_add_u64(&var, pg_atomic_read_u64(&var) - 2) != 3)
|
EXPECT_EQ_U64(pg_atomic_sub_fetch_u64(&var, 3), 0);
|
||||||
elog(ERROR, "atomic_fetch_add_u64() #1 wrong");
|
EXPECT_EQ_U64(pg_atomic_add_fetch_u64(&var, 10), 10);
|
||||||
|
EXPECT_EQ_U64(pg_atomic_exchange_u64(&var, 5), 10);
|
||||||
if (pg_atomic_fetch_sub_u64(&var, 1) != 4)
|
EXPECT_EQ_U64(pg_atomic_exchange_u64(&var, 0), 5);
|
||||||
elog(ERROR, "atomic_fetch_sub_u64() #1 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_sub_fetch_u64(&var, 3) != 0)
|
|
||||||
elog(ERROR, "atomic_sub_fetch_u64() #1 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_add_fetch_u64(&var, 10) != 10)
|
|
||||||
elog(ERROR, "atomic_add_fetch_u64() #1 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_exchange_u64(&var, 5) != 10)
|
|
||||||
elog(ERROR, "pg_atomic_exchange_u64() #1 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_exchange_u64(&var, 0) != 5)
|
|
||||||
elog(ERROR, "pg_atomic_exchange_u64() #0 wrong");
|
|
||||||
|
|
||||||
/* fail exchange because of old expected */
|
/* fail exchange because of old expected */
|
||||||
expected = 10;
|
expected = 10;
|
||||||
if (pg_atomic_compare_exchange_u64(&var, &expected, 1))
|
EXPECT_TRUE(!pg_atomic_compare_exchange_u64(&var, &expected, 1));
|
||||||
elog(ERROR, "atomic_compare_exchange_u64() changed value spuriously");
|
|
||||||
|
|
||||||
/* CAS is allowed to fail due to interrupts, try a couple of times */
|
/* CAS is allowed to fail due to interrupts, try a couple of times */
|
||||||
for (i = 0; i < 100; i++)
|
for (i = 0; i < 100; i++)
|
||||||
|
@ -1092,31 +1039,19 @@ test_atomic_uint64(void)
|
||||||
}
|
}
|
||||||
if (i == 100)
|
if (i == 100)
|
||||||
elog(ERROR, "atomic_compare_exchange_u64() never succeeded");
|
elog(ERROR, "atomic_compare_exchange_u64() never succeeded");
|
||||||
if (pg_atomic_read_u64(&var) != 1)
|
EXPECT_EQ_U64(pg_atomic_read_u64(&var), 1);
|
||||||
elog(ERROR, "atomic_compare_exchange_u64() didn't set value properly");
|
|
||||||
|
|
||||||
pg_atomic_write_u64(&var, 0);
|
pg_atomic_write_u64(&var, 0);
|
||||||
|
|
||||||
/* try setting flagbits */
|
/* try setting flagbits */
|
||||||
if (pg_atomic_fetch_or_u64(&var, 1) & 1)
|
EXPECT_TRUE(!(pg_atomic_fetch_or_u64(&var, 1) & 1));
|
||||||
elog(ERROR, "pg_atomic_fetch_or_u64() #1 wrong");
|
EXPECT_TRUE(pg_atomic_fetch_or_u64(&var, 2) & 1);
|
||||||
|
EXPECT_EQ_U64(pg_atomic_read_u64(&var), 3);
|
||||||
if (!(pg_atomic_fetch_or_u64(&var, 2) & 1))
|
|
||||||
elog(ERROR, "pg_atomic_fetch_or_u64() #2 wrong");
|
|
||||||
|
|
||||||
if (pg_atomic_read_u64(&var) != 3)
|
|
||||||
elog(ERROR, "invalid result after pg_atomic_fetch_or_u64()");
|
|
||||||
|
|
||||||
/* try clearing flagbits */
|
/* try clearing flagbits */
|
||||||
if ((pg_atomic_fetch_and_u64(&var, ~2) & 3) != 3)
|
EXPECT_EQ_U64((pg_atomic_fetch_and_u64(&var, ~2) & 3), 3);
|
||||||
elog(ERROR, "pg_atomic_fetch_and_u64() #1 wrong");
|
EXPECT_EQ_U64(pg_atomic_fetch_and_u64(&var, ~1), 1);
|
||||||
|
|
||||||
if (pg_atomic_fetch_and_u64(&var, ~1) != 1)
|
|
||||||
elog(ERROR, "pg_atomic_fetch_and_u64() #2 wrong: is " UINT64_FORMAT,
|
|
||||||
pg_atomic_read_u64(&var));
|
|
||||||
/* no bits set anymore */
|
/* no bits set anymore */
|
||||||
if (pg_atomic_fetch_and_u64(&var, ~0) != 0)
|
EXPECT_EQ_U64(pg_atomic_fetch_and_u64(&var, ~0), 0);
|
||||||
elog(ERROR, "pg_atomic_fetch_and_u64() #3 wrong");
|
|
||||||
}
|
}
|
||||||
#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */
|
#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue