utest.cpp
Go to the documentation of this file.
00001 //  Copyright (c) 2009 Helge Bahmann
00002 //
00003 //  Distributed under the Boost Software License, Version 1.0.
00004 //  See accompanying file LICENSE_1_0.txt or copy at
00005 //  http://www.boost.org/LICENSE_1_0.txt)
00006 
00007 #include <boost/memory_order.hpp>
00008 #include "ros/atomic.h"
00009 #include <typeinfo>
00010 
00011 #include <gtest/gtest.h>
00012 
00013 using namespace ros;
00014 
00015 
00016 template<typename T>
00017 void test_atomic_arithmetic(void)
00018 {
00019         atomic<T> i(41);
00020 
00021         T n;
00022 
00023         fprintf(stderr, "Type=%s, size=%ld, atomic_size=%ld, lockfree=%d\n",
00024                 typeid(T).name(), (long)sizeof(n), (long)sizeof(i), i.is_lock_free());
00025 
00026         ASSERT_TRUE(sizeof(i)>=sizeof(n));
00027 
00028         bool success;
00029 
00030         n=i++;
00031         ASSERT_TRUE(i==42);
00032         ASSERT_TRUE(n==41);
00033 
00034         n=i--;
00035         ASSERT_TRUE(n==42);
00036         ASSERT_TRUE(i==41);
00037 
00038         n=++i;
00039         ASSERT_TRUE(i==42);
00040         ASSERT_TRUE(n==42);
00041 
00042         n=--i;
00043         ASSERT_TRUE(n==41);
00044         ASSERT_TRUE(i==41);
00045 
00046         n=i.fetch_and(15);
00047         ASSERT_TRUE(n==41);
00048         ASSERT_TRUE(i==9);
00049 
00050         n=i.fetch_or(17);
00051         ASSERT_TRUE(n==9);
00052         ASSERT_TRUE(i==25);
00053 
00054         n=i.fetch_xor(3);
00055         ASSERT_TRUE(n==25);
00056         ASSERT_TRUE(i==26);
00057 
00058         n=i.exchange(12);
00059         ASSERT_TRUE(n==26);
00060         ASSERT_TRUE(i==12);
00061 
00062         n=12;
00063         success=i.compare_exchange_strong(n, 17);
00064         ASSERT_TRUE(success);
00065         ASSERT_TRUE(n==12);
00066         ASSERT_TRUE(i==17);
00067 
00068         n=12;
00069         success=i.compare_exchange_strong(n, 19);
00070         ASSERT_TRUE(!success);
00071         ASSERT_TRUE(n==17);
00072         ASSERT_TRUE(i==17);
00073 }
00074 
00075 template<typename T>
00076 void test_atomic_base(void)
00077 {
00078         atomic<T> i;
00079         T n;
00080 
00081         fprintf(stderr, "Type=%s, size=%ld, atomic_size=%ld, lockfree=%d\n",
00082                 typeid(T).name(), (long)sizeof(n), (long)sizeof(i), i.is_lock_free());
00083 
00084         ASSERT_TRUE(sizeof(i)>=sizeof(n));
00085 
00086         bool success;
00087 
00088         i.store((T)0);
00089         n=(T)40;
00090         success=i.compare_exchange_strong(n, (T)44 /*boost::memory_order_relaxed*/);
00091         ASSERT_TRUE(!success);
00092         ASSERT_TRUE(n==(T)0);
00093         ASSERT_TRUE(i.load()==(T)0);
00094 
00095         n=(T)0;
00096         success=i.compare_exchange_strong(n, (T)44);
00097         ASSERT_TRUE(success);
00098         ASSERT_TRUE(n==(T)0);
00099         ASSERT_TRUE(i.load()==(T)44);
00100 
00101         n=i.exchange((T)20);
00102         ASSERT_EQ(n, (T)44);
00103         ASSERT_TRUE(i.load()==(T)20);
00104 }
00105 
00106 template<typename T>
00107 void test_atomic_ptr(void)
00108 {
00109         test_atomic_base<T *>();
00110 
00111         T array[10], *p;
00112         atomic<T *> ptr;
00113 
00114         ptr=&array[0];
00115 
00116         p=ptr++;
00117         ASSERT_TRUE(p==&array[0]);
00118         ASSERT_TRUE(ptr==&array[1]);
00119         p=++ptr;
00120         ASSERT_TRUE(p==&array[2]);
00121         ASSERT_TRUE(ptr==&array[2]);
00122 
00123         p=ptr.fetch_add(4);
00124         ASSERT_TRUE(p==&array[2]);
00125         ASSERT_TRUE(ptr==&array[6]);
00126 
00127         p=ptr.fetch_sub(4);
00128         ASSERT_TRUE(p==&array[6]);
00129         ASSERT_TRUE(ptr==&array[2]);
00130 
00131         p=ptr--;
00132         ASSERT_TRUE(p==&array[2]);
00133         ASSERT_TRUE(ptr==&array[1]);
00134         p=--ptr;
00135         ASSERT_TRUE(p==&array[0]);
00136         ASSERT_TRUE(ptr==&array[0]);
00137 }
00138 
00139 template<>
00140 void test_atomic_base<bool>(void)
00141 {
00142         atomic<bool> i;
00143         bool n;
00144 
00145         fprintf(stderr, "Type=bool, size=%ld, atomic_size=%ld, lockfree=%d\n",
00146                 (long)sizeof(n), (long)sizeof(i), i.is_lock_free());
00147 
00148         ASSERT_TRUE(sizeof(i)>=sizeof(n));
00149 
00150         bool success;
00151         i=false;
00152         n=true;
00153         success=i.compare_exchange_strong(n, true);
00154         ASSERT_TRUE(!success);
00155         ASSERT_TRUE(n==false);
00156         ASSERT_TRUE(i==false);
00157 
00158         n=false;
00159         success=i.compare_exchange_strong(n, true);
00160         ASSERT_TRUE(success);
00161         ASSERT_TRUE(n==false);
00162         ASSERT_TRUE(i==true);
00163 
00164         n=i.exchange(false);
00165         ASSERT_TRUE(n==true);
00166         ASSERT_TRUE(i==false);
00167 }
00168 
00169 void test_atomic_flag()
00170 {
00171         atomic_flag f;
00172 
00173         ASSERT_TRUE(!f.test_and_set());
00174         ASSERT_TRUE(f.test_and_set());
00175         f.clear();
00176         ASSERT_TRUE(!f.test_and_set());
00177 }
00178 
00179 struct Compound {
00180         int i;
00181 
00182         inline bool operator==(const Compound &c) const {return i==c.i;}
00183 };
00184 
00185 void test_atomic_struct(void)
00186 {
00187         atomic<Compound> i;
00188         Compound n;
00189 
00190         Compound zero={0}, one={1}, two={2};
00191 
00192         ASSERT_TRUE(sizeof(i)>=sizeof(n));
00193 
00194         bool success;
00195 
00196         i.store(zero);
00197         n=one;
00198         success=i.compare_exchange_strong(n, two);
00199         ASSERT_TRUE(!success);
00200         ASSERT_TRUE(n==zero);
00201         ASSERT_TRUE(i.load()==zero);
00202 
00203         n=zero;
00204         success=i.compare_exchange_strong(n, two);
00205         ASSERT_TRUE(success);
00206         ASSERT_TRUE(n==zero);
00207         ASSERT_TRUE(i.load()==two);
00208 
00209         n=i.exchange(one);
00210         ASSERT_TRUE(n==two);
00211         ASSERT_TRUE(i.load()==one);
00212 }
00213 
00214 enum TestEnum {
00215         Foo, Bar, Baz=1000
00216 };
00217 
00218 void test_fence()
00219 {
00220         atomic_thread_fence(memory_order_acquire);
00221 }
00222 
00223 TEST(Atomic, all)
00224 {
00225   test_atomic_arithmetic<char>();
00226   test_atomic_arithmetic<signed char>();
00227   test_atomic_arithmetic<unsigned char>();
00228   test_atomic_arithmetic<uint8_t>();
00229   test_atomic_arithmetic<int8_t>();
00230   test_atomic_arithmetic<short>();
00231   test_atomic_arithmetic<unsigned short>();
00232   test_atomic_arithmetic<uint16_t>();
00233   test_atomic_arithmetic<int16_t>();
00234   test_atomic_arithmetic<int>();
00235   test_atomic_arithmetic<unsigned int>();
00236   test_atomic_arithmetic<uint32_t>();
00237   test_atomic_arithmetic<int32_t>();
00238   test_atomic_arithmetic<long>();
00239   test_atomic_arithmetic<unsigned long>();
00240   test_atomic_arithmetic<uint64_t>();
00241   test_atomic_arithmetic<int64_t>();
00242   test_atomic_arithmetic<long long>();
00243   test_atomic_arithmetic<unsigned long long>();
00244 
00245   test_atomic_struct();
00246 
00247   test_atomic_base<void *>();
00248   test_atomic_ptr<int>();
00249   test_atomic_base<bool>();
00250   test_atomic_base<TestEnum>();
00251 
00252   atomic_thread_fence(memory_order_seq_cst);
00253 
00254   test_fence();
00255 
00256   test_atomic_flag();
00257 }
00258 
00259 int main(int argc, char** argv)
00260 {
00261   testing::InitGoogleTest(&argc, argv);
00262   return RUN_ALL_TESTS();
00263 }


rosatomic
Author(s): Josh Faust
autogenerated on Sat Dec 28 2013 17:34:27