diff options
author | Chris Manton <cmanton@google.com> | 2014-08-13 11:00:17 -0700 |
---|---|---|
committer | Andre Eisenbach <eisenbach@google.com> | 2015-03-16 16:51:28 -0700 |
commit | 87a62cb71860d0d14061c9c279f399d355affc2e (patch) | |
tree | d9264f030b1940c0c2ce93204d7360821c76a28a | |
parent | 97fd2c0c1b45f21015ff51f5185e3b47680fdd1f (diff) | |
download | android_system_bt-87a62cb71860d0d14061c9c279f399d355affc2e.tar.gz android_system_bt-87a62cb71860d0d14061c9c279f399d355affc2e.tar.bz2 android_system_bt-87a62cb71860d0d14061c9c279f399d355affc2e.zip |
Extend add/subtract operations to atomics
Going to be used for counters
-rw-r--r-- | osi/include/atomic.h | 16 | ||||
-rw-r--r-- | osi/test/atomic_test.cpp | 33 |
2 files changed, 48 insertions, 1 deletions
diff --git a/osi/include/atomic.h b/osi/include/atomic.h index 171a5393f..beac2f151 100644 --- a/osi/include/atomic.h +++ b/osi/include/atomic.h @@ -86,6 +86,18 @@ inline type atomic_dec_postfix_##name(volatile atomic_##name##_t *atomic) { \ return __atomic_fetch_sub_##sz(atomic, 1, __ATOMIC_SEQ_CST); \ } +// Returns value after operation, e.g. new value +#define ATOMIC_ADD(name, type, sz) \ +inline type atomic_add_##name(volatile atomic_##name##_t *atomic, type val) { \ + return __atomic_add_fetch_##sz(atomic, val, __ATOMIC_SEQ_CST); \ +} + +// Returns value after operation, e.g. new value +#define ATOMIC_SUB(name, type, sz) \ +inline type atomic_sub_##name(volatile atomic_##name##_t *atomic, type val) { \ + return __atomic_sub_fetch_##sz(atomic, val, __ATOMIC_SEQ_CST); \ +} + #define ATOMIC_MAKE(name, type, sz) \ ATOMIC_TYPE(name, type) \ ATOMIC_STORE(name, type, sz) \ @@ -93,7 +105,9 @@ inline type atomic_dec_postfix_##name(volatile atomic_##name##_t *atomic) { \ ATOMIC_INC_PREFIX(name, type, sz) \ ATOMIC_DEC_PREFIX(name, type, sz) \ ATOMIC_INC_POSTFIX(name, type, sz) \ - ATOMIC_DEC_POSTFIX(name, type, sz) + ATOMIC_DEC_POSTFIX(name, type, sz) \ + ATOMIC_ADD(name, type, sz) \ + ATOMIC_SUB(name, type, sz) ATOMIC_MAKE(s32, int32_t, 4) ATOMIC_MAKE(u32, uint32_t, 4) diff --git a/osi/test/atomic_test.cpp b/osi/test/atomic_test.cpp index bed4733e0..b0039ab3f 100644 --- a/osi/test/atomic_test.cpp +++ b/osi/test/atomic_test.cpp @@ -243,3 +243,36 @@ TEST(AtomicTest, test_inc_dec_s64) { EXPECT_EQ(-1, val); EXPECT_EQ(-2, atomic_load_s64(&data)); } + +TEST(AtomicTest, test_add_sub_u64) { + atomic_u64_t data; + + atomic_store_u64(&data, 0); + EXPECT_EQ((unsigned)0, atomic_load_u64(&data)); + + uint64_t val = atomic_add_u64(&data, 0xffff); + EXPECT_EQ((unsigned)0xffff, atomic_load_u64(&data)); + EXPECT_EQ((unsigned)0xffff, val); + + val = atomic_add_u64(&data, 0xffff); + EXPECT_EQ((unsigned)(2 * 0xffff), atomic_load_u64(&data)); + EXPECT_EQ((unsigned)(2 * 0xffff), val); + + val = atomic_add_u64(&data, 0xffff); + EXPECT_EQ((unsigned)(3 * 0xffff), atomic_load_u64(&data)); + EXPECT_EQ((unsigned)(3 * 0xffff), val); + EXPECT_NE((unsigned)(3 * 0xfff0), val); + + val = atomic_sub_u64(&data, 0xffff); + EXPECT_EQ((unsigned)(2 * 0xffff), val); + + val = atomic_sub_u64(&data, 0); + EXPECT_EQ((unsigned)(2 * 0xffff), val); + val = atomic_sub_u64(&data, 0xffff); + EXPECT_EQ((unsigned)(1 * 0xffff), val); + + val = atomic_sub_u64(&data, 0xffff); + EXPECT_EQ((unsigned)0, val); +} + + |