stdatomic_test.cpp revision 34b258dd692951ab2236e134e5520367cda60125
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <gtest/gtest.h> 18 19#if !defined(__GLIBC__) /* TODO: fix our prebuilt toolchains! */ 20 21#include <stdatomic.h> 22 23TEST(stdatomic, LOCK_FREE) { 24 ASSERT_TRUE(ATOMIC_BOOL_LOCK_FREE); 25 ASSERT_TRUE(ATOMIC_CHAR16_T_LOCK_FREE); 26 ASSERT_TRUE(ATOMIC_CHAR32_T_LOCK_FREE); 27 ASSERT_TRUE(ATOMIC_CHAR_LOCK_FREE); 28 ASSERT_TRUE(ATOMIC_INT_LOCK_FREE); 29 ASSERT_TRUE(ATOMIC_LLONG_LOCK_FREE); 30 ASSERT_TRUE(ATOMIC_LONG_LOCK_FREE); 31 ASSERT_TRUE(ATOMIC_POINTER_LOCK_FREE); 32 ASSERT_TRUE(ATOMIC_SHORT_LOCK_FREE); 33 ASSERT_TRUE(ATOMIC_WCHAR_T_LOCK_FREE); 34} 35 36TEST(stdatomic, init) { 37 atomic_int v = ATOMIC_VAR_INIT(123); 38 ASSERT_EQ(123, atomic_load(&v)); 39 40 atomic_init(&v, 456); 41 ASSERT_EQ(456, atomic_load(&v)); 42 43 atomic_flag f = ATOMIC_FLAG_INIT; 44 ASSERT_FALSE(atomic_flag_test_and_set(&f)); 45} 46 47TEST(stdatomic, atomic_thread_fence) { 48 atomic_thread_fence(memory_order_relaxed); 49 atomic_thread_fence(memory_order_consume); 50 atomic_thread_fence(memory_order_acquire); 51 atomic_thread_fence(memory_order_release); 52 atomic_thread_fence(memory_order_acq_rel); 53 atomic_thread_fence(memory_order_seq_cst); 54} 55 56TEST(stdatomic, atomic_signal_fence) { 57 atomic_signal_fence(memory_order_relaxed); 58 atomic_signal_fence(memory_order_consume); 59 atomic_signal_fence(memory_order_acquire); 60 atomic_signal_fence(memory_order_release); 61 atomic_signal_fence(memory_order_acq_rel); 62 atomic_signal_fence(memory_order_seq_cst); 63} 64 65TEST(stdatomic, atomic_is_lock_free) { 66 atomic_char small; 67 atomic_intmax_t big; 68 ASSERT_TRUE(atomic_is_lock_free(&small)); 69 // atomic_intmax_t(size = 64) is not lock free on mips32. 70#if defined(__mips__) && !defined(__LP64__) 71 ASSERT_FALSE(atomic_is_lock_free(&big)); 72#else 73 ASSERT_TRUE(atomic_is_lock_free(&big)); 74#endif 75} 76 77TEST(stdatomic, atomic_flag) { 78 atomic_flag f = ATOMIC_FLAG_INIT; 79 ASSERT_FALSE(atomic_flag_test_and_set(&f)); 80 ASSERT_TRUE(atomic_flag_test_and_set(&f)); 81 82 atomic_flag_clear(&f); 83 84 ASSERT_FALSE(atomic_flag_test_and_set_explicit(&f, memory_order_relaxed)); 85 ASSERT_TRUE(atomic_flag_test_and_set_explicit(&f, memory_order_relaxed)); 86 87 atomic_flag_clear_explicit(&f, memory_order_relaxed); 88 ASSERT_FALSE(atomic_flag_test_and_set_explicit(&f, memory_order_relaxed)); 89} 90 91TEST(stdatomic, atomic_store) { 92 atomic_int i; 93 atomic_store(&i, 123); 94 ASSERT_EQ(123, atomic_load(&i)); 95 atomic_store_explicit(&i, 123, memory_order_relaxed); 96 ASSERT_EQ(123, atomic_load_explicit(&i, memory_order_relaxed)); 97} 98 99TEST(stdatomic, atomic_exchange) { 100 atomic_int i; 101 atomic_store(&i, 123); 102 ASSERT_EQ(123, atomic_exchange(&i, 456)); 103 ASSERT_EQ(456, atomic_exchange_explicit(&i, 123, memory_order_relaxed)); 104} 105 106TEST(stdatomic, atomic_compare_exchange) { 107 atomic_int i; 108 int expected; 109 110 atomic_store(&i, 123); 111 expected = 123; 112 ASSERT_TRUE(atomic_compare_exchange_strong(&i, &expected, 456)); 113 ASSERT_FALSE(atomic_compare_exchange_strong(&i, &expected, 456)); 114 ASSERT_EQ(456, expected); 115 116 atomic_store(&i, 123); 117 expected = 123; 118 ASSERT_TRUE(atomic_compare_exchange_strong_explicit(&i, &expected, 456, memory_order_relaxed, memory_order_relaxed)); 119 ASSERT_FALSE(atomic_compare_exchange_strong_explicit(&i, &expected, 456, memory_order_relaxed, memory_order_relaxed)); 120 ASSERT_EQ(456, expected); 121 122 atomic_store(&i, 123); 123 expected = 123; 124 ASSERT_TRUE(atomic_compare_exchange_weak(&i, &expected, 456)); 125 ASSERT_FALSE(atomic_compare_exchange_weak(&i, &expected, 456)); 126 ASSERT_EQ(456, expected); 127 128 atomic_store(&i, 123); 129 expected = 123; 130 ASSERT_TRUE(atomic_compare_exchange_weak_explicit(&i, &expected, 456, memory_order_relaxed, memory_order_relaxed)); 131 ASSERT_FALSE(atomic_compare_exchange_weak_explicit(&i, &expected, 456, memory_order_relaxed, memory_order_relaxed)); 132 ASSERT_EQ(456, expected); 133} 134 135TEST(stdatomic, atomic_fetch_add) { 136 atomic_int i = ATOMIC_VAR_INIT(123); 137 ASSERT_EQ(123, atomic_fetch_add(&i, 1)); 138 ASSERT_EQ(124, atomic_fetch_add_explicit(&i, 1, memory_order_relaxed)); 139 ASSERT_EQ(125, atomic_load(&i)); 140} 141 142TEST(stdatomic, atomic_fetch_sub) { 143 atomic_int i = ATOMIC_VAR_INIT(123); 144 ASSERT_EQ(123, atomic_fetch_sub(&i, 1)); 145 ASSERT_EQ(122, atomic_fetch_sub_explicit(&i, 1, memory_order_relaxed)); 146 ASSERT_EQ(121, atomic_load(&i)); 147} 148 149TEST(stdatomic, atomic_fetch_or) { 150 atomic_int i = ATOMIC_VAR_INIT(0x100); 151 ASSERT_EQ(0x100, atomic_fetch_or(&i, 0x020)); 152 ASSERT_EQ(0x120, atomic_fetch_or_explicit(&i, 0x003, memory_order_relaxed)); 153 ASSERT_EQ(0x123, atomic_load(&i)); 154} 155 156TEST(stdatomic, atomic_fetch_xor) { 157 atomic_int i = ATOMIC_VAR_INIT(0x100); 158 ASSERT_EQ(0x100, atomic_fetch_xor(&i, 0x120)); 159 ASSERT_EQ(0x020, atomic_fetch_xor_explicit(&i, 0x103, memory_order_relaxed)); 160 ASSERT_EQ(0x123, atomic_load(&i)); 161} 162 163TEST(stdatomic, atomic_fetch_and) { 164 atomic_int i = ATOMIC_VAR_INIT(0x123); 165 ASSERT_EQ(0x123, atomic_fetch_and(&i, 0x00f)); 166 ASSERT_EQ(0x003, atomic_fetch_and_explicit(&i, 0x2, memory_order_relaxed)); 167 ASSERT_EQ(0x002, atomic_load(&i)); 168} 169 170#endif 171