summaryrefslogtreecommitdiffstats
path: root/osi/test/atomic_test.cpp
diff options
context:
space:
mode:
authorChris Manton <cmanton@google.com>2014-07-30 10:51:07 -0700
committerAndre Eisenbach <eisenbach@google.com>2015-03-16 16:51:28 -0700
commit52f0230cc9c30a1473f9fdc7ddf0ff9f4a62d2e1 (patch)
tree78c62356225bd36fb57fe258b72d6fa6de8d4310 /osi/test/atomic_test.cpp
parenteba49154be47a080b8e730b7688eafdfebf8e16e (diff)
downloadandroid_system_bt-52f0230cc9c30a1473f9fdc7ddf0ff9f4a62d2e1.tar.gz
android_system_bt-52f0230cc9c30a1473f9fdc7ddf0ff9f4a62d2e1.tar.bz2
android_system_bt-52f0230cc9c30a1473f9fdc7ddf0ff9f4a62d2e1.zip
osi: Support for atomic data types
Diffstat (limited to 'osi/test/atomic_test.cpp')
-rw-r--r--osi/test/atomic_test.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/osi/test/atomic_test.cpp b/osi/test/atomic_test.cpp
new file mode 100644
index 000000000..1d4601f74
--- /dev/null
+++ b/osi/test/atomic_test.cpp
@@ -0,0 +1,176 @@
+#include <gtest/gtest.h>
+
+extern "C" {
+#include "atomic.h"
+}
+
+const static size_t ATOMIC_DATA_MAX = 2;
+const static int ATOMIC_MAX_THREADS = 20;
+
+struct atomic_test_s32_s {
+ pthread_t pthread_id;
+ int thread_num;
+ int max_val;
+ atomic_s32_t *data;
+};
+
+void *atomic_thread(void *context) {
+ struct atomic_test_s32_s *at = (struct atomic_test_s32_s *)context;
+ for (int i = 0; i < at->max_val; i++) {
+ usleep(1);
+ atomic_inc_prefix_s32(&at->data[i]);
+ }
+ return NULL;
+}
+
+void *atomic_thread_inc_dec(void *context) {
+ struct atomic_test_s32_s *at = (struct atomic_test_s32_s *)context;
+ for (int i = 0; i < at->max_val; i++) {
+ usleep(1);
+ atomic_inc_prefix_s32(&at->data[i]);
+ usleep(1);
+ atomic_dec_prefix_s32(&at->data[i]);
+ }
+ return NULL;
+}
+
+TEST(AtomicTest, test_store_load_s32) {
+ atomic_s32_t data;
+
+ atomic_store_s32(&data, -1);
+ EXPECT_EQ(-1, atomic_load_s32(&data));
+
+ atomic_store_s32(&data, 0);
+ EXPECT_EQ(0, atomic_load_s32(&data));
+
+ atomic_store_s32(&data, 1);
+ EXPECT_EQ(1, atomic_load_s32(&data));
+
+ atomic_store_s32(&data, 2);
+ EXPECT_EQ(2, atomic_load_s32(&data));
+}
+
+TEST(AtomicTest, test_store_load_u32) {
+ atomic_u32_t data;
+
+ atomic_store_u32(&data, -1);
+ EXPECT_EQ((uint32_t)-1, atomic_load_u32(&data));
+
+ atomic_store_u32(&data, 0);
+ EXPECT_EQ((uint32_t)0, atomic_load_u32(&data));
+
+ atomic_store_u32(&data, 1);
+ EXPECT_EQ((uint32_t)1, atomic_load_u32(&data));
+
+ atomic_store_u32(&data, 2);
+ EXPECT_EQ((uint32_t)2, atomic_load_u32(&data));
+}
+
+TEST(AtomicTest, test_inc_dec_s32) {
+ atomic_s32_t data;
+
+ atomic_store_s32(&data, 0);
+ EXPECT_EQ(0, atomic_load_s32(&data));
+
+ int32_t val = atomic_inc_prefix_s32(&data);
+ EXPECT_EQ(1, atomic_load_s32(&data));
+ EXPECT_EQ(1, val);
+
+ val = atomic_inc_prefix_s32(&data);
+ EXPECT_EQ(2, atomic_load_s32(&data));
+ EXPECT_EQ(2, val);
+
+ val = atomic_inc_prefix_s32(&data);
+ EXPECT_EQ(3, atomic_load_s32(&data));
+ EXPECT_EQ(3, val);
+
+ val = atomic_dec_prefix_s32(&data);
+ EXPECT_EQ(2, val);
+
+ val = atomic_dec_prefix_s32(&data);
+ EXPECT_EQ(1, val);
+ val = atomic_dec_prefix_s32(&data);
+ EXPECT_EQ(0, val);
+ val = atomic_dec_prefix_s32(&data);
+ EXPECT_EQ(-1, val);
+}
+
+TEST(AtomicTest, test_inc_dec_u32) {
+ atomic_u32_t data;
+
+ atomic_store_u32(&data, 0);
+ EXPECT_EQ((unsigned)0, atomic_load_u32(&data));
+
+ uint32_t val = atomic_inc_prefix_u32(&data);
+ EXPECT_EQ((unsigned)1, atomic_load_u32(&data));
+ EXPECT_EQ((unsigned)1, val);
+
+ val = atomic_inc_prefix_u32(&data);
+ EXPECT_EQ((unsigned)2, atomic_load_u32(&data));
+ EXPECT_EQ((unsigned)2, val);
+
+ val = atomic_inc_prefix_u32(&data);
+ EXPECT_EQ((unsigned)3, atomic_load_u32(&data));
+ EXPECT_EQ((unsigned)3, val);
+
+ val = atomic_dec_prefix_u32(&data);
+ EXPECT_EQ((unsigned)2, val);
+
+ val = atomic_dec_prefix_u32(&data);
+ EXPECT_EQ((unsigned)1, val);
+ val = atomic_dec_prefix_u32(&data);
+ EXPECT_EQ((unsigned)0, val);
+ val = atomic_dec_prefix_u32(&data);
+ EXPECT_EQ((unsigned)-1, val);
+}
+
+TEST(AtomicTest, test_atomic_inc_thread) {
+ struct atomic_test_s32_s atomic_test[ATOMIC_MAX_THREADS];
+ atomic_s32_t data[ATOMIC_DATA_MAX];
+
+ memset(&atomic_test, 0, sizeof(atomic_test));
+ memset(data, 0, sizeof(data));
+
+ for (unsigned int i = 0; i < ATOMIC_DATA_MAX; i++) {
+ EXPECT_EQ(0, data[i]._val);
+ }
+
+ for (int i = 0; i < ATOMIC_MAX_THREADS; i++) {
+ atomic_test[i].thread_num = i;
+ atomic_test[i].max_val = ATOMIC_DATA_MAX;
+ atomic_test[i].data = data;
+ pthread_create(&atomic_test[i].pthread_id, NULL, atomic_thread, &atomic_test[i]);
+ }
+
+ for (int i = 0; i < ATOMIC_MAX_THREADS; i++) {
+ int rc = pthread_join(atomic_test[i].pthread_id, NULL);
+ EXPECT_EQ(0, rc);
+ }
+
+ for (unsigned int i = 0; i < ATOMIC_DATA_MAX; i++) {
+ EXPECT_EQ(1 * ATOMIC_MAX_THREADS, data[i]._val);
+ }
+}
+
+TEST(AtomicTest, test_atomic_inc_thread_single) {
+ struct atomic_test_s32_s atomic_test[ATOMIC_MAX_THREADS];
+ atomic_s32_t data;
+
+ memset(&atomic_test, 0, sizeof(atomic_test));
+ memset(&data, 0, sizeof(data));
+
+ EXPECT_EQ(0, data._val);
+
+ for (int i = 0; i < ATOMIC_MAX_THREADS; i++) {
+ atomic_test[i].thread_num = i;
+ atomic_test[i].max_val = 1;
+ atomic_test[i].data = &data;
+ pthread_create(&atomic_test[i].pthread_id, NULL, atomic_thread_inc_dec, &atomic_test[i]);
+ }
+
+ for (int i = 0; i < ATOMIC_MAX_THREADS; i++) {
+ int rc = pthread_join(atomic_test[i].pthread_id, NULL);
+ EXPECT_EQ(0, rc);
+ }
+ EXPECT_EQ(0, data._val);
+}