00001 //--------------------------------------------------------------------------- 00002 /** @file LinkedListTest.cpp 00003 */ 00004 //--------------------------------------------------------------------------- 00005 00006 #include "SgSystem.h" 00007 #include "SgRandom.h" 00008 00009 #include <boost/thread.hpp> 00010 #include <boost/thread/mutex.hpp> 00011 #include <boost/thread/barrier.hpp> 00012 #include <boost/shared_ptr.hpp> 00013 #include <boost/test/auto_unit_test.hpp> 00014 00015 #include "LinkedList.hpp" 00016 00017 using namespace benzene; 00018 00019 //--------------------------------------------------------------------------- 00020 00021 /** Set to true if verify correctness in lock-free mode. */ 00022 #define TEST_THREADING 0 00023 00024 //--------------------------------------------------------------------------- 00025 00026 namespace { 00027 00028 Pool<int> pool; 00029 00030 BOOST_AUTO_TEST_CASE(LinkedList_BasicAdd) 00031 { 00032 LinkedList<int> a(pool); 00033 00034 BOOST_CHECK(a.Empty()); 00035 00036 a.Add(2); 00037 a.Add(3); 00038 a.Add(1); 00039 a.Add(7); 00040 a.Add(4); 00041 a.Add(3); 00042 a.Add(2); 00043 a.Add(1); 00044 a.Add(7); 00045 00046 BOOST_CHECK(!a.Empty()); 00047 00048 ListIterator<int> it(a); 00049 BOOST_CHECK(it); 00050 BOOST_CHECK_EQUAL(*it, 1); 00051 ++it; 00052 BOOST_CHECK(it); 00053 BOOST_CHECK_EQUAL(*it, 2); 00054 ++it; 00055 BOOST_CHECK(it); 00056 BOOST_CHECK_EQUAL(*it, 3); 00057 ++it; 00058 BOOST_CHECK(it); 00059 BOOST_CHECK_EQUAL(*it, 4); 00060 ++it; 00061 BOOST_CHECK(it); 00062 BOOST_CHECK_EQUAL(*it, 7); 00063 ++it; 00064 BOOST_CHECK(!it); 00065 } 00066 00067 BOOST_AUTO_TEST_CASE(LinkedList_BasicRemove) 00068 { 00069 LinkedList<int> a(pool); 00070 00071 BOOST_CHECK(a.Empty()); 00072 00073 a.Add(1); 00074 a.Remove(1); 00075 BOOST_CHECK(a.Empty()); 00076 00077 a.Add(1); 00078 a.Remove(2); 00079 BOOST_CHECK(!a.Empty()); 00080 00081 { 00082 ListIterator<int> it(a); 00083 BOOST_CHECK(it); 00084 BOOST_CHECK_EQUAL(*it, 1); 00085 ++it; 00086 BOOST_CHECK(!it); 00087 } 00088 00089 a.Add(2); 00090 a.Add(3); 00091 a.Remove(2); 00092 { 00093 ListIterator<int> it(a); 00094 BOOST_CHECK(it); 00095 BOOST_CHECK_EQUAL(*it, 1); 00096 ++it; 00097 BOOST_CHECK(it); 00098 BOOST_CHECK_EQUAL(*it, 3); 00099 ++it; 00100 BOOST_CHECK(!it); 00101 } 00102 00103 a.Remove(1); 00104 { 00105 ListIterator<int> it(a); 00106 BOOST_CHECK(it); 00107 BOOST_CHECK_EQUAL(*it, 3); 00108 ++it; 00109 BOOST_CHECK(!it); 00110 } 00111 00112 a.Remove(3); 00113 { 00114 BOOST_CHECK(a.Empty()); 00115 ListIterator<int> it(a); 00116 BOOST_CHECK(!it); 00117 } 00118 } 00119 00120 #if TEST_THREADING 00121 00122 struct Thread 00123 { 00124 int m_threadId; 00125 00126 boost::barrier& m_barrier; 00127 00128 LinkedList<int>& m_lst; 00129 00130 SgRandom m_random; 00131 00132 Thread(int threadId, boost::barrier& b, LinkedList<int>& l) 00133 : m_threadId(threadId), m_barrier(b), m_lst(l) 00134 { 00135 }; 00136 00137 void operator()() 00138 { 00139 m_barrier.wait(); 00140 for (int i = 0; i < 100; ++i) 00141 { 00142 if (m_threadId && (i % m_threadId == 0)) 00143 { 00144 int num = m_random.Int(100); 00145 int count = 0; 00146 for (ListIterator<int> it(m_lst); it; ++it, ++count) 00147 { 00148 if (count == num) 00149 { 00150 m_lst.Remove(*it); 00151 break; 00152 } 00153 } 00154 } 00155 m_lst.Add(m_random.Int(100000) / (m_threadId+1)); 00156 } 00157 } 00158 }; 00159 00160 BOOST_AUTO_TEST_CASE(LinkedList_Threading) 00161 { 00162 const int NUM_THREADS = 10; 00163 LinkedList<int> a(pool); 00164 std::vector<boost::shared_ptr<boost::thread> > threads; 00165 boost::barrier barrier(NUM_THREADS + 1); 00166 for (int i = 0; i < NUM_THREADS; ++i) 00167 { 00168 Thread runnable(i, barrier, a); 00169 boost::shared_ptr<boost::thread> thread(new boost::thread(runnable)); 00170 threads.push_back(thread); 00171 } 00172 barrier.wait(); 00173 for (int i = 0; i < NUM_THREADS; ++i) 00174 { 00175 threads[i]->join(); 00176 } 00177 std::cout << '['; 00178 for (ListIterator<int> it(a); it; ++it) 00179 std::cout << *it << ", "; 00180 std::cout << "]\n"; 00181 00182 ListIterator<int> it(a); 00183 int old = *it; 00184 ++it; 00185 while (it) 00186 { 00187 00188 BOOST_CHECK(old < *it); 00189 old = *it; 00190 ++it; 00191 } 00192 } 00193 00194 #endif // TEST_THREADING 00195 00196 } 00197 00198 //---------------------------------------------------------------------------