static void test_atomic_uint64(void) { pg_atomic_uint64 var; uint64 expected; int i; pg_atomic_init_u64(&var, 0); if (pg_atomic_read_u64(&var) != 0) elog(ERROR, "atomic_read_u64() #1 wrong"); pg_atomic_write_u64(&var, 3); if (pg_atomic_read_u64(&var) != 3) elog(ERROR, "atomic_read_u64() #2 wrong"); if (pg_atomic_fetch_add_u64(&var, 1) != 3) elog(ERROR, "atomic_fetch_add_u64() #1 wrong"); if (pg_atomic_fetch_sub_u64(&var, 1) != 4) 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 */ expected = 10; if (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 */ for (i = 0; i < 100; i++) { expected = 0; if (!pg_atomic_compare_exchange_u64(&var, &expected, 1)) break; } if (i == 100) elog(ERROR, "atomic_compare_exchange_u64() never succeeded"); if (pg_atomic_read_u64(&var) != 1) elog(ERROR, "atomic_compare_exchange_u64() didn't set value properly"); pg_atomic_write_u64(&var, 0); /* try setting flagbits */ if (pg_atomic_fetch_or_u64(&var, 1) & 1) elog(ERROR, "pg_atomic_fetch_or_u64() #1 wrong"); 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 */ if ((pg_atomic_fetch_and_u64(&var, ~2) & 3) != 3) elog(ERROR, "pg_atomic_fetch_and_u64() #1 wrong"); 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 */ if (pg_atomic_fetch_and_u64(&var, ~0) != 0) elog(ERROR, "pg_atomic_fetch_and_u64() #3 wrong"); }
void Cache_DecPerfCounter64(int64 *counter, int64 delta) { Assert(counter - delta >= 0); pg_atomic_sub_fetch_u64((pg_atomic_uint64 *) counter,delta); }