1 // The MIT License (MIT) 2 // 3 // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 // THE SOFTWARE. 22 23 #include "Tests.h" 24 #include <UnitTest++.h> 25 #include <MTScheduler.h> 26 #include <MTQueueMPMC.h> 27 #include <MTConcurrentRingBuffer.h> 28 #include <MTArrayView.h> 29 #include <MTStaticVector.h> 30 31 SUITE(FoundationTests) 32 { 33 34 35 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 36 TEST(RingBufferTest) 37 { 38 MT::ConcurrentRingBuffer<int, 32> ringBuffer; 39 40 ringBuffer.Push(-1); 41 ringBuffer.Push(1); 42 43 int tempData[32]; 44 size_t elementsCount = ringBuffer.PopAll(tempData, MT_ARRAY_SIZE(tempData)); 45 CHECK_EQUAL(elementsCount, (size_t)2); 46 47 CHECK_EQUAL(tempData[0], -1); 48 CHECK_EQUAL(tempData[1], 1); 49 50 int j; 51 for(j = 0; j < 507; j++) 52 { 53 ringBuffer.Push(3 + j); 54 } 55 56 elementsCount = ringBuffer.PopAll(tempData, MT_ARRAY_SIZE(tempData)); 57 CHECK_EQUAL(elementsCount, (size_t)32); 58 59 size_t i; 60 for(i = 0; i < elementsCount; i++) 61 { 62 CHECK_EQUAL(tempData[i], (int)((507+3-32) + i)); 63 } 64 65 } 66 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 67 TEST(StackArrayTest) 68 { 69 const int elementsCount = 128; 70 71 MT::StaticVector<int, elementsCount> stackArray; 72 73 CHECK(stackArray.IsEmpty() == true); 74 75 stackArray.PushBack(200); 76 CHECK(stackArray.IsEmpty() == false); 77 CHECK_EQUAL(stackArray.Size(), (size_t)1); 78 79 for(int i = 1; i < elementsCount; i++) 80 { 81 stackArray.PushBack(200 + i); 82 } 83 84 CHECK(stackArray.IsEmpty() == false); 85 CHECK_EQUAL(stackArray.Size(), (size_t)elementsCount); 86 87 for(int i = 0; i < elementsCount; i++) 88 { 89 CHECK_EQUAL(stackArray[i], (200 + i)); 90 } 91 92 } 93 94 95 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 96 TEST(QueueMPMC_BasicTest) 97 { 98 MT::LockFreeQueueMPMC<int, 32> queue; 99 100 for(int i = 0; i < 64; i++) 101 { 102 bool res = queue.TryPush( std::move(77 + i) ); 103 if (i < 32) 104 { 105 CHECK_EQUAL(true, res); 106 } else 107 { 108 CHECK_EQUAL(false, res); 109 } 110 } 111 112 for(int i = 0; i < 64; i++) 113 { 114 int val; 115 bool res = queue.TryPop(val); 116 if (i < 32) 117 { 118 CHECK_EQUAL(true, res); 119 CHECK_EQUAL(77 + i, val); 120 } else 121 { 122 CHECK_EQUAL(false, res); 123 } 124 } 125 126 127 CHECK_EQUAL(true, queue.TryPush( 113 )); 128 CHECK_EQUAL(true, queue.TryPush( 114 )); 129 CHECK_EQUAL(true, queue.TryPush( 115 )); 130 131 int v; 132 CHECK_EQUAL(true, queue.TryPop(v)); 133 CHECK_EQUAL(113, v); 134 135 CHECK_EQUAL(true, queue.TryPush( 116 )); 136 CHECK_EQUAL(true, queue.TryPush( 117 )); 137 CHECK_EQUAL(true, queue.TryPush( 118 )); 138 139 CHECK_EQUAL(true, queue.TryPop(v)); 140 CHECK_EQUAL(114, v); 141 CHECK_EQUAL(true, queue.TryPop(v)); 142 CHECK_EQUAL(115, v); 143 CHECK_EQUAL(true, queue.TryPop(v)); 144 CHECK_EQUAL(116, v); 145 CHECK_EQUAL(true, queue.TryPop(v)); 146 CHECK_EQUAL(117, v); 147 CHECK_EQUAL(true, queue.TryPop(v)); 148 CHECK_EQUAL(118, v); 149 150 v = -133; 151 CHECK_EQUAL(false, queue.TryPop(v)); 152 CHECK_EQUAL(-133, v); 153 154 } 155 156 157 158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 159 TEST(ArrayViewTest) 160 { 161 162 MT::ArrayView<int> emptyArrayView(nullptr, 0); 163 CHECK(emptyArrayView.IsEmpty() == true); 164 165 const int elementsCount = 128; 166 void* rawMemory = MT::Memory::Alloc(sizeof(int) * elementsCount); 167 168 MT::ArrayView<int> arrayView(rawMemory, elementsCount); 169 CHECK(arrayView.IsEmpty() == false); 170 171 for (int i = 0; i < elementsCount; i++) 172 { 173 arrayView[i] = (100 + i); 174 } 175 176 const int* buffer = static_cast<const int*>(rawMemory); 177 for (int i = 0; i < elementsCount; i++) 178 { 179 CHECK_EQUAL(buffer[i], arrayView[i]); 180 } 181 182 MT::Memory::Free(rawMemory); 183 } 184 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 185 186 } 187