00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef DEQUETEST_H_
00017 #define DEQUETEST_H_
00018 #include <cppunit/extensions/HelperMacros.h>
00019 #include <cppunit/TestAssert.h>
00020 #include <stdexcept>
00021
00022 #include "baseTest.h"
00023
00024 namespace test {
00025 using namespace amino;
00026
00027 template<typename DequeType, typename ParaType, char const* CLASS_NAME>
00028 class DequeTest: public CppUnit::TestFixture, public BaseTest<ParaType> {
00029 CPPUNIT_TEST_SUITE(DequeTest);
00030 CPPUNIT_TEST(testPushRightMT);
00031 CPPUNIT_TEST(test4DirectionMT);
00032 CPPUNIT_TEST(testBoundLeft);
00033 CPPUNIT_TEST(testBoundRight);
00034 CPPUNIT_TEST_SUITE_END();
00035
00036 private:
00037 DequeType *deque;
00038 public:
00039 DequeTest() {
00040 }
00041
00042 DequeType * getDeque() {
00043 return deque;
00044 }
00045
00046 void setUp() {
00047 deque = new DequeType();
00048 }
00049
00050 void reset() {
00051 delete deque;
00052 deque = new DequeType();
00053 }
00054
00055 void tearDown() {
00056 delete deque;
00057 }
00058
00062 void testPushRightMT();
00063 void test4DirectionMT();
00064
00065 void testBoundLeft();
00066 void testBoundRight();
00067 };
00068
00069 template<typename DequeType, typename ParaType, char const* CLASS_NAME>
00070 class Thread4Dir: public TestThread<ParaType> {
00071 private:
00072 DequeType *deque;
00073 DequeTest<DequeType, ParaType, CLASS_NAME> *testcase;
00074 int elementNum;
00075 int operationNum;
00076
00077 public:
00078 Thread4Dir(DequeType * q, DequeTest<DequeType, ParaType, CLASS_NAME> * qt,
00079 int nElement, int nOperation) :
00080 deque(q), testcase(qt), elementNum(nElement), operationNum(nOperation) {
00081 }
00082
00083 static atomic<ParaType> checksum;
00084
00085 static ParaType getChecksum() {
00086 return checksum.load(memory_order_relaxed);
00087 }
00088
00089 void* run() {
00090 for (int i = 0; i < operationNum; ++i) {
00091 if (i % 2 == 0) {
00092 deque->pushRight(testcase->data[i%((this->threadId+1)*elementNum)]);
00093 this->inVec.push_back(testcase->data[i%((this->threadId+1)*elementNum)]);
00094 try {
00095 ParaType tmp;
00096 if(deque->popLeft(tmp)) {
00097 this->outVec.push_back(tmp);
00098 }
00099
00100 if (i % 7 == 0) {
00101 if(deque->popLeft(tmp)) {
00102 this->outVec.push_back(tmp);
00103 }
00104 }
00105 } catch (std::range_error e) {
00106 }
00107 } else {
00108 deque->pushLeft(testcase->data[i%((this->threadId+1)*elementNum)]);
00109 this->inVec.push_back(testcase->data[i%((this->threadId+1)*elementNum)]);
00110 ParaType tmp;
00111 try {
00112 if(deque->popRight(tmp)) {
00113 this->outVec.push_back(tmp);
00114 }
00115
00116 if (i % 7 == 0) {
00117 if(deque->popLeft(tmp)) {
00118 this->outVec.push_back(tmp);
00119 }
00120 }
00121 } catch (std::range_error e) {
00122 }
00123 }
00124 }
00125 return NULL;
00126 }
00127 };
00128
00129 template<typename DequeType, typename ParaType, const char * CLASS_NAME>
00130 atomic<ParaType> Thread4Dir<DequeType, ParaType, CLASS_NAME>::checksum;
00131
00132 template<typename DequeType, typename ParaType, char const* CLASS_NAME>
00133 class ThreadPushRight: public TestThread<ParaType> {
00134 private:
00135 DequeType *deque;
00136 DequeTest<DequeType, ParaType, CLASS_NAME> *testcase;
00137 int elementNum;
00138 int operationNum;
00139
00140 public:
00141 ThreadPushRight(DequeType * q,
00142 DequeTest<DequeType, ParaType, CLASS_NAME> * qt, int nElement, int nOperation) :
00143 deque(q), testcase(qt), elementNum(nElement),operationNum(nOperation) {
00144 }
00145
00146 static atomic<ParaType> checksum;
00147
00148 static ParaType getChecksum() {
00149 return checksum.load(memory_order_relaxed);
00150 }
00151
00152 void* run() {
00153 for (int i = 0; i < operationNum; ++i) {
00154 if (i % 2 == 0) {
00155 deque->pushRight(testcase->data[i%((this->threadId+1)*elementNum)]);
00156 this->inVec.push_back(testcase->data[i%((this->threadId+1)*elementNum)]);
00157 } else {
00158 deque->pushLeft(testcase->data[i%((this->threadId+1)*elementNum)]);
00159 this->inVec.push_back(testcase->data[i%((this->threadId+1)*elementNum)]);
00160 }
00161 }
00162 return NULL;
00163 }
00164 };
00165
00166 template<typename DequeType, typename ParaType, const char * CLASS_NAME>
00167 atomic<ParaType> ThreadPushRight<DequeType, ParaType, CLASS_NAME>::checksum;
00168
00169 template<typename DequeType, typename ParaType, const char * CLASS_NAME>
00170 class ThreadPushRightFactory: public ThreadFactory<ParaType> {
00171 private:
00172 DequeType *deque;
00173 DequeTest<DequeType, ParaType, CLASS_NAME> *testcase;
00174 public:
00175 ThreadPushRightFactory(DequeType * q, DequeTest<DequeType, ParaType,
00176 CLASS_NAME> * qt) :
00177 deque(q), testcase(qt) {
00178 }
00179
00180 virtual Runnable ** createThreads(int threadNum, int elementNum,
00181 int operationNum) {
00182 testcase->reset();
00183 deque = testcase->getDeque();
00184
00185 this->inVec.clear();
00186 this->outVec.clear();
00187
00188 ThreadPushRight<DequeType, ParaType, CLASS_NAME>::checksum = 0;
00189
00190 Runnable ** threads;
00191 threads = new Runnable*[threadNum];
00192 for (int i = 0; i < threadNum; ++i)
00193 threads[i] = new ThreadPushRight<DequeType, ParaType, CLASS_NAME> (
00194 deque, testcase, elementNum, operationNum);
00195
00196 return threads;
00197 }
00198
00199 typedef ThreadPushRight<DequeType, ParaType, CLASS_NAME> ThreadPushRight_T;
00200
00201 virtual void verifyResult(int threadNum, int elementNum) {
00202 while (!deque->empty()) {
00203 ParaType tmp;
00204 if(deque->popRight(tmp)) {
00205 this->outVec.push_back(tmp);
00206 }
00207 }
00208 cout << this->outVec.size() << endl;
00209 ThreadFactory<ParaType>::verifyResult(threadNum, elementNum);
00210 }
00211
00212 };
00213
00214 template<typename DequeType, typename ParaType, char const* CLASS_NAME>
00215 class Thread4DirFactory: public ThreadFactory<ParaType> {
00216 private:
00217 DequeType *deque;
00218 DequeTest<DequeType, ParaType, CLASS_NAME> *testcase;
00219
00220 public:
00221 Thread4DirFactory(DequeType * q,
00222 DequeTest<DequeType, ParaType, CLASS_NAME> * qt) :
00223 deque(q), testcase(qt) {
00224 }
00225 virtual Runnable ** createThreads(int threadNum, int elementNum,
00226 int operationNum) {
00227 testcase->reset();
00228 deque = testcase->getDeque();
00229
00230 this->inVec.clear();
00231 this->outVec.clear();
00232
00233 Thread4Dir<DequeType, ParaType, CLASS_NAME>::checksum = 0;
00234
00235 Runnable ** threads;
00236 threads = new Runnable*[threadNum];
00237 for (int i = 0; i < threadNum; ++i)
00238 threads[i]
00239 = new Thread4Dir<DequeType, ParaType, CLASS_NAME> (deque, testcase, elementNum, operationNum);
00240
00241 return threads;
00242 }
00243
00244 typedef Thread4Dir<DequeType, ParaType, CLASS_NAME> Thread4Dir_T;
00245 };
00246
00247 template<typename DequeType, typename ParaType, const char * CLASS_NAME>
00248 void DequeTest<DequeType, ParaType, CLASS_NAME>::testPushRightMT() {
00249 ThreadPushRightFactory<DequeType, ParaType, CLASS_NAME> dequeueFactory(
00250 deque, this);
00251 ThreadRunner::runThreads(&dequeueFactory, CLASS_NAME, "testPushRightMT");
00252 }
00253
00254 template<typename DequeType, typename ParaType, const char * CLASS_NAME>
00255 void DequeTest<DequeType, ParaType, CLASS_NAME>::test4DirectionMT() {
00256 Thread4DirFactory<DequeType, ParaType, CLASS_NAME> dequeueFactory(deque,
00257 this);
00258 ThreadRunner::runThreads(&dequeueFactory, CLASS_NAME, "testDequeMT");
00259 }
00260
00261 template<typename DequeType, typename ParaType, const char * CLASS_NAME>
00262 void DequeTest<DequeType, ParaType, CLASS_NAME>::testBoundLeft() {
00263 ParaType tmp;
00264 bool res = deque->popLeft(tmp);
00265
00266 CPPUNIT_ASSERT(!res);
00267 }
00268
00269 template<typename DequeType, typename ParaType, const char * CLASS_NAME>
00270 void DequeTest<DequeType, ParaType, CLASS_NAME>::testBoundRight() {
00271 ParaType tmp;
00272 bool res = deque->popRight(tmp);
00273
00274 CPPUNIT_ASSERT(!res);
00275 }
00276 }
00277 #endif