mfbt/tests/TestAtomics.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "mozilla/Assertions.h"
     6 #include "mozilla/Atomics.h"
     8 #include <stdint.h>
    10 using mozilla::Atomic;
    11 using mozilla::MemoryOrdering;
    12 using mozilla::Relaxed;
    13 using mozilla::ReleaseAcquire;
    14 using mozilla::SequentiallyConsistent;
    16 template <typename T, MemoryOrdering Order>
    17 static void
    18 TestTypeWithOrdering()
    19 {
    20   Atomic<T, Order> atomic(5);
    21   MOZ_RELEASE_ASSERT(atomic == 5, "Atomic variable did not initialize");
    23   // Test atomic increment
    24   MOZ_RELEASE_ASSERT(++atomic == T(6), "Atomic increment did not work");
    25   MOZ_RELEASE_ASSERT(atomic++ == T(6), "Atomic post-increment did not work");
    26   MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic post-increment did not work");
    28   // Test atomic decrement
    29   MOZ_RELEASE_ASSERT(--atomic == 6, "Atomic decrement did not work");
    30   MOZ_RELEASE_ASSERT(atomic-- == 6, "Atomic post-decrement did not work");
    31   MOZ_RELEASE_ASSERT(atomic == 5, "Atomic post-decrement did not work");
    33   // Test other arithmetic.
    34   T result;
    35   result = (atomic += T(5));
    36   MOZ_RELEASE_ASSERT(atomic == T(10), "Atomic += did not work");
    37   MOZ_RELEASE_ASSERT(result == T(10), "Atomic += returned the wrong value");
    38   result = (atomic -= T(3));
    39   MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic -= did not work");
    40   MOZ_RELEASE_ASSERT(result == T(7), "Atomic -= returned the wrong value");
    42   // Test assignment
    43   result = (atomic = T(5));
    44   MOZ_RELEASE_ASSERT(atomic == T(5), "Atomic assignment failed");
    45   MOZ_RELEASE_ASSERT(result == T(5), "Atomic assignment returned the wrong value");
    47   // Test logical operations.
    48   result = (atomic ^= T(2));
    49   MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic ^= did not work");
    50   MOZ_RELEASE_ASSERT(result == T(7), "Atomic ^= returned the wrong value");
    51   result = (atomic ^= T(4));
    52   MOZ_RELEASE_ASSERT(atomic == T(3), "Atomic ^= did not work");
    53   MOZ_RELEASE_ASSERT(result == T(3), "Atomic ^= returned the wrong value");
    54   result = (atomic |= T(8));
    55   MOZ_RELEASE_ASSERT(atomic == T(11), "Atomic |= did not work");
    56   MOZ_RELEASE_ASSERT(result == T(11), "Atomic |= returned the wrong value");
    57   result = (atomic |= T(8));
    58   MOZ_RELEASE_ASSERT(atomic == T(11), "Atomic |= did not work");
    59   MOZ_RELEASE_ASSERT(result == T(11), "Atomic |= returned the wrong value");
    60   result = (atomic &= T(12));
    61   MOZ_RELEASE_ASSERT(atomic == T(8), "Atomic &= did not work");
    62   MOZ_RELEASE_ASSERT(result == T(8), "Atomic &= returned the wrong value");
    64   // Test exchange.
    65   atomic = T(30);
    66   result = atomic.exchange(42);
    67   MOZ_RELEASE_ASSERT(atomic == T(42), "Atomic exchange did not work");
    68   MOZ_RELEASE_ASSERT(result == T(30), "Atomic exchange returned the wrong value");
    70   // Test CAS.
    71   atomic = T(1);
    72   bool boolResult = atomic.compareExchange(0, 2);
    73   MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
    74   MOZ_RELEASE_ASSERT(atomic == T(1), "CAS shouldn't have done anything.");
    76   boolResult = atomic.compareExchange(1, 42);
    77   MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
    78   MOZ_RELEASE_ASSERT(atomic == T(42), "CAS should have changed atomic's value.");
    79 }
    81 template<typename T, MemoryOrdering Order>
    82 static void
    83 TestPointerWithOrdering()
    84 {
    85   T array1[10];
    86   Atomic<T*, Order> atomic(array1);
    87   MOZ_RELEASE_ASSERT(atomic == array1, "Atomic variable did not initialize");
    89   // Test atomic increment
    90   MOZ_RELEASE_ASSERT(++atomic == array1 + 1, "Atomic increment did not work");
    91   MOZ_RELEASE_ASSERT(atomic++ == array1 + 1, "Atomic post-increment did not work");
    92   MOZ_RELEASE_ASSERT(atomic == array1 + 2, "Atomic post-increment did not work");
    94   // Test atomic decrement
    95   MOZ_RELEASE_ASSERT(--atomic == array1 + 1, "Atomic decrement did not work");
    96   MOZ_RELEASE_ASSERT(atomic-- == array1 + 1, "Atomic post-decrement did not work");
    97   MOZ_RELEASE_ASSERT(atomic == array1, "Atomic post-decrement did not work");
    99   // Test other arithmetic operations
   100   T* result;
   101   result = (atomic += 2);
   102   MOZ_RELEASE_ASSERT(atomic == array1 + 2, "Atomic += did not work");
   103   MOZ_RELEASE_ASSERT(result == array1 + 2, "Atomic += returned the wrong value");
   104   result = (atomic -= 1);
   105   MOZ_RELEASE_ASSERT(atomic == array1 + 1, "Atomic -= did not work");
   106   MOZ_RELEASE_ASSERT(result == array1 + 1, "Atomic -= returned the wrong value");
   108   // Test stores
   109   result = (atomic = array1);
   110   MOZ_RELEASE_ASSERT(atomic == array1, "Atomic assignment did not work");
   111   MOZ_RELEASE_ASSERT(result == array1, "Atomic assignment returned the wrong value");
   113   // Test exchange
   114   atomic = array1 + 2;
   115   result = atomic.exchange(array1);
   116   MOZ_RELEASE_ASSERT(atomic == array1, "Atomic exchange did not work");
   117   MOZ_RELEASE_ASSERT(result == array1 + 2, "Atomic exchange returned the wrong value");
   119   atomic = array1;
   120   bool boolResult = atomic.compareExchange(array1 + 1, array1 + 2);
   121   MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
   122   MOZ_RELEASE_ASSERT(atomic == array1, "CAS shouldn't have done anything.");
   124   boolResult = atomic.compareExchange(array1, array1 + 3);
   125   MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
   126   MOZ_RELEASE_ASSERT(atomic == array1 + 3, "CAS should have changed atomic's value.");
   127 }
   129 enum EnumType {
   130   EnumType_0 = 0,
   131   EnumType_1 = 1,
   132   EnumType_2 = 2,
   133   EnumType_3 = 3
   134 };
   136 template<MemoryOrdering Order>
   137 static void
   138 TestEnumWithOrdering()
   139 {
   140   Atomic<EnumType, Order> atomic(EnumType_2);
   141   MOZ_RELEASE_ASSERT(atomic == EnumType_2, "Atomic variable did not initialize");
   143   // Test assignment
   144   EnumType result;
   145   result = (atomic = EnumType_3);
   146   MOZ_RELEASE_ASSERT(atomic == EnumType_3, "Atomic assignment failed");
   147   MOZ_RELEASE_ASSERT(result == EnumType_3, "Atomic assignment returned the wrong value");
   149   // Test exchange.
   150   atomic = EnumType_1;
   151   result = atomic.exchange(EnumType_2);
   152   MOZ_RELEASE_ASSERT(atomic == EnumType_2, "Atomic exchange did not work");
   153   MOZ_RELEASE_ASSERT(result == EnumType_1, "Atomic exchange returned the wrong value");
   155   // Test CAS.
   156   atomic = EnumType_1;
   157   bool boolResult = atomic.compareExchange(EnumType_0, EnumType_2);
   158   MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
   159   MOZ_RELEASE_ASSERT(atomic == EnumType_1, "CAS shouldn't have done anything.");
   161   boolResult = atomic.compareExchange(EnumType_1, EnumType_3);
   162   MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
   163   MOZ_RELEASE_ASSERT(atomic == EnumType_3, "CAS should have changed atomic's value.");
   164 }
   166 template <MemoryOrdering Order>
   167 static void
   168 TestBoolWithOrdering()
   169 {
   170   Atomic<bool, Order> atomic(false);
   171   MOZ_RELEASE_ASSERT(atomic == false, "Atomic variable did not initialize");
   173   // Test assignment
   174   bool result;
   175   result = (atomic = true);
   176   MOZ_RELEASE_ASSERT(atomic == true, "Atomic assignment failed");
   177   MOZ_RELEASE_ASSERT(result == true, "Atomic assignment returned the wrong value");
   179   // Test exchange.
   180   atomic = false;
   181   result = atomic.exchange(true);
   182   MOZ_RELEASE_ASSERT(atomic == true, "Atomic exchange did not work");
   183   MOZ_RELEASE_ASSERT(result == false, "Atomic exchange returned the wrong value");
   185   // Test CAS.
   186   atomic = false;
   187   bool boolResult = atomic.compareExchange(true, false);
   188   MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
   189   MOZ_RELEASE_ASSERT(atomic == false, "CAS shouldn't have done anything.");
   191   boolResult = atomic.compareExchange(false, true);
   192   MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
   193   MOZ_RELEASE_ASSERT(atomic == true, "CAS should have changed atomic's value.");
   194 }
   196 template <typename T>
   197 static void
   198 TestType()
   199 {
   200   TestTypeWithOrdering<T, SequentiallyConsistent>();
   201   TestTypeWithOrdering<T, ReleaseAcquire>();
   202   TestTypeWithOrdering<T, Relaxed>();
   203 }
   205 template<typename T>
   206 static void
   207 TestPointer()
   208 {
   209   TestPointerWithOrdering<T, SequentiallyConsistent>();
   210   TestPointerWithOrdering<T, ReleaseAcquire>();
   211   TestPointerWithOrdering<T, Relaxed>();
   212 }
   214 static void
   215 TestEnum()
   216 {
   217   TestEnumWithOrdering<SequentiallyConsistent>();
   218   TestEnumWithOrdering<ReleaseAcquire>();
   219   TestEnumWithOrdering<Relaxed>();
   220 }
   222 static void
   223 TestBool()
   224 {
   225   TestBoolWithOrdering<SequentiallyConsistent>();
   226   TestBoolWithOrdering<ReleaseAcquire>();
   227   TestBoolWithOrdering<Relaxed>();
   228 }
   230 int main()
   231 {
   232   TestType<uint32_t>();
   233   TestType<int32_t>();
   234   TestType<intptr_t>();
   235   TestType<uintptr_t>();
   236   TestPointer<int>();
   237   TestPointer<float>();
   238   TestPointer<uint16_t*>();
   239   TestPointer<uint32_t*>();
   240   TestEnum();
   241   TestBool();
   242 }

mercurial