diff options
Diffstat (limited to 'src/third_party/gperftools-2.7/dist/src/tests/atomicops_unittest.cc')
-rw-r--r-- | src/third_party/gperftools-2.7/dist/src/tests/atomicops_unittest.cc | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/third_party/gperftools-2.7/dist/src/tests/atomicops_unittest.cc b/src/third_party/gperftools-2.7/dist/src/tests/atomicops_unittest.cc new file mode 100644 index 00000000000..aa82a6b56ee --- /dev/null +++ b/src/third_party/gperftools-2.7/dist/src/tests/atomicops_unittest.cc @@ -0,0 +1,162 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- +/* Copyright (c) 2006, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * --- + * Author: Sanjay Ghemawat + */ + +#include <stdio.h> +#include "base/logging.h" +#include "base/atomicops.h" + +#define GG_ULONGLONG(x) static_cast<uint64>(x) + + +#define NUM_BITS(T) (sizeof(T) * 8) + + +template <class AtomicType> +static void TestCompareAndSwap(AtomicType (*compare_and_swap_func) + (volatile AtomicType*, AtomicType, AtomicType)) { + AtomicType value = 0; + AtomicType prev = (*compare_and_swap_func)(&value, 0, 1); + ASSERT_EQ(1, value); + ASSERT_EQ(0, prev); + + // Use test value that has non-zero bits in both halves, more for testing + // 64-bit implementation on 32-bit platforms. + const AtomicType k_test_val = (GG_ULONGLONG(1) << + (NUM_BITS(AtomicType) - 2)) + 11; + value = k_test_val; + prev = (*compare_and_swap_func)(&value, 0, 5); + ASSERT_EQ(k_test_val, value); + ASSERT_EQ(k_test_val, prev); + + value = k_test_val; + prev = (*compare_and_swap_func)(&value, k_test_val, 5); + ASSERT_EQ(5, value); + ASSERT_EQ(k_test_val, prev); +} + + +template <class AtomicType> +static void TestAtomicExchange(AtomicType (*atomic_exchange_func) + (volatile AtomicType*, AtomicType)) { + AtomicType value = 0; + AtomicType new_value = (*atomic_exchange_func)(&value, 1); + ASSERT_EQ(1, value); + ASSERT_EQ(0, new_value); + + // Use test value that has non-zero bits in both halves, more for testing + // 64-bit implementation on 32-bit platforms. + const AtomicType k_test_val = (GG_ULONGLONG(1) << + (NUM_BITS(AtomicType) - 2)) + 11; + value = k_test_val; + new_value = (*atomic_exchange_func)(&value, k_test_val); + ASSERT_EQ(k_test_val, value); + ASSERT_EQ(k_test_val, new_value); + + value = k_test_val; + new_value = (*atomic_exchange_func)(&value, 5); + ASSERT_EQ(5, value); + ASSERT_EQ(k_test_val, new_value); +} + + +// This is a simple sanity check that values are correct. Not testing +// atomicity +template <class AtomicType> +static void TestStore() { + const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL); + const AtomicType kVal2 = static_cast<AtomicType>(-1); + + AtomicType value; + + base::subtle::NoBarrier_Store(&value, kVal1); + ASSERT_EQ(kVal1, value); + base::subtle::NoBarrier_Store(&value, kVal2); + ASSERT_EQ(kVal2, value); + + base::subtle::Acquire_Store(&value, kVal1); + ASSERT_EQ(kVal1, value); + base::subtle::Acquire_Store(&value, kVal2); + ASSERT_EQ(kVal2, value); + + base::subtle::Release_Store(&value, kVal1); + ASSERT_EQ(kVal1, value); + base::subtle::Release_Store(&value, kVal2); + ASSERT_EQ(kVal2, value); +} + +// This is a simple sanity check that values are correct. Not testing +// atomicity +template <class AtomicType> +static void TestLoad() { + const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL); + const AtomicType kVal2 = static_cast<AtomicType>(-1); + + AtomicType value; + + value = kVal1; + ASSERT_EQ(kVal1, base::subtle::NoBarrier_Load(&value)); + value = kVal2; + ASSERT_EQ(kVal2, base::subtle::NoBarrier_Load(&value)); + + value = kVal1; + ASSERT_EQ(kVal1, base::subtle::Acquire_Load(&value)); + value = kVal2; + ASSERT_EQ(kVal2, base::subtle::Acquire_Load(&value)); + + value = kVal1; + ASSERT_EQ(kVal1, base::subtle::Release_Load(&value)); + value = kVal2; + ASSERT_EQ(kVal2, base::subtle::Release_Load(&value)); +} + +template <class AtomicType> +static void TestAtomicOps() { + TestCompareAndSwap<AtomicType>(base::subtle::NoBarrier_CompareAndSwap); + TestCompareAndSwap<AtomicType>(base::subtle::Acquire_CompareAndSwap); + TestCompareAndSwap<AtomicType>(base::subtle::Release_CompareAndSwap); + + TestAtomicExchange<AtomicType>(base::subtle::NoBarrier_AtomicExchange); + TestAtomicExchange<AtomicType>(base::subtle::Acquire_AtomicExchange); + TestAtomicExchange<AtomicType>(base::subtle::Release_AtomicExchange); + + TestStore<AtomicType>(); + TestLoad<AtomicType>(); +} + +int main(int argc, char** argv) { + TestAtomicOps<AtomicWord>(); + TestAtomicOps<Atomic32>(); + printf("PASS\n"); + return 0; +} |