static void test_basic_operations() { IOQueue<int> queue; assert(!queue); queue.push(1); assert(queue); assert(queue.front() == 1); assert(queue.size() == 1); queue.pop(); assert(!queue); assert(queue.size() == 0); queue.push(2); assert(queue); assert(queue.front() == 2); assert(queue.size() == 1); queue.push(3); assert(queue); assert(queue.front() == 2); assert(queue.size() == 2); queue.pop(); assert(queue); assert(queue.front() == 3); assert(queue.size() == 1); queue.pop(); assert(!queue); assert(queue.size() == 0); }
static void test_thread_safety() { std::atomic<int> count(0); std::atomic<int> push_count(0); IOQueue<std::function<void()>> queue; auto consumer = std::thread( [&queue, &count] { while (count.load() < 9000000) { if (queue) { queue.front()(); queue.pop(); } } } ); auto producer_func = [&queue, &push_count, &count] { while (push_count.fetch_add(1) < 9000000) { queue.push([&count] { ++count; }); } }; auto producer_1 = std::thread([&producer_func]{ producer_func(); }); auto producer_2 = std::thread([&producer_func]{ producer_func(); }); auto producer_3 = std::thread([&producer_func]{ producer_func(); }); auto producer_4 = std::thread([&producer_func]{ producer_func(); }); auto producer_5 = std::thread([&producer_func]{ producer_func(); }); auto producer_6 = std::thread([&producer_func]{ producer_func(); }); auto producer_7 = std::thread([&producer_func]{ producer_func(); }); producer_1.join(); producer_2.join(); producer_3.join(); producer_4.join(); producer_5.join(); producer_6.join(); producer_7.join(); consumer.join(); }
static void test(uint32_t size) { requestdata_t *input = new requestdata_t[size]; requestdata_t *output = new requestdata_t[size]; for(int k = 0; k < 10; ++k) { IOQueue q; uint32_t i, j; iorequest_t req(NULL); assert(size); debug_randomize(input, intsizeof(requestdata_t[size])); debug_randomize(output, intsizeof(requestdata_t[size])); // push all for(i = 0; i < size; ++i) { q.push(iorequest_t(&input[i])); } // pop all for(i = 0; i < size; ++i) { assert(q.tryPop(&req)); output[i].offset = req.getOffset(); } assert(q.empty()); //test_print(output, size); // check order for(i = 0; i < size-1; ++i) { ASSERT(output[i].offset <= output[i+1].offset, cerr << '[' << i << "]:" << output[i].offset << " > [" << i+1 << "]:" << output[i+1].offset << endl); } // ordered push partial j = RAND()%size; for(i = 0; i < j; ++i) { q.push(iorequest_t(&output[i])); } // pop and push for(i = 0; i < j; ++i) { assert(q.tryPop(&req)); assert(output[i].offset == req.getOffset()); if (rand()%2 == 0 && j < size) { q.push(iorequest_t(&output[j])); j++; } } } delete [] output; delete [] input; }