diff --git a/tests/tst-queue-mpsc.hh b/tests/tst-queue-mpsc.hh index 0853db611673b7843879bd067a491d492bfe8c09..1cb14c5a3c9113f95fb1971d1d1e074adda923c0 100644 --- a/tests/tst-queue-mpsc.hh +++ b/tests/tst-queue-mpsc.hh @@ -9,39 +9,33 @@ class test_queue_mpsc : public unit_tests::vtest { public: - struct test_threads_data { - sched::thread* main; - sched::thread* t1; - bool t1ok; - sched::thread* t2; - bool t2ok; - int test_ctr; + struct info { + lockfree::queue_mpsc<int> *q; + int len; + lockfree::linked_item<int> *items; }; - - void test_thread_1(test_threads_data& tt) + void push_thread(struct info *in) { - while (tt.test_ctr < 1000) { - sched::thread::wait_until([&] { return (tt.test_ctr % 2) == 0; }); - ++tt.test_ctr; - if (tt.t2ok) { - tt.t2->wake(); - } + for(int i=0; i<in->len; i++){ + in->items[i].value = i; + in->q->push(&in->items[i]); } - tt.t1ok = false; - tt.main->wake(); } - void test_thread_2(test_threads_data& tt) + void pop_thread(struct info *in) { - while (tt.test_ctr < 1000) { - sched::thread::wait_until([&] { return (tt.test_ctr % 2) == 1; }); - ++tt.test_ctr; - if (tt.t1ok) { - tt.t1->wake(); + int sum=0, something=0, nothing=0; + while(something<in->len){ + int n = in->q->pop(); + if(n<0) + nothing++; + else { + something++; + sum+=n; } } - tt.t2ok = false; - tt.main->wake(); + + debug(fmt("pop_thread saw something %d times, nothing %d times. sum: %d") % something % nothing % sum); } void run() @@ -59,10 +53,8 @@ public: assert(q.pop()==7); assert(q.pop()==-1); assert(q.isempty()); - debug("test3"); - - int len=10; + int len=1000; auto items = new lockfree::linked_item<int>[len]; for(int i=0; i<len; i++){ items[i].value = i*i; @@ -75,20 +67,35 @@ public: assert(q.pop()==-1); assert(q.isempty()); delete[] items; - - test_threads_data tt; - tt.main = sched::thread::current(); - tt.t1ok = tt.t2ok = true; - tt.t1 = new sched::thread([&] { test_thread_1(tt); }); - tt.t2 = new sched::thread([&] { test_thread_2(tt); }); - tt.test_ctr = 0; - tt.t1->start(); - tt.t2->start(); - sched::thread::wait_until([&] { return tt.test_ctr >= 1000; }); - tt.t1->join(); - tt.t2->join(); - delete tt.t1; - delete tt.t2; + // A very basic multi-threaded test - 3 threads pushing, 1 popping + len=1000; + auto items1 = new lockfree::linked_item<int>[len]; + auto items2 = new lockfree::linked_item<int>[len]; + auto items3 = new lockfree::linked_item<int>[len]; + struct info info1 = { &q, len, items1 }; + struct info info2 = { &q, len, items2 }; + struct info info3 = { &q, len, items3 }; + struct info infop = { &q, len*3, nullptr }; + auto t1 = new sched::thread([&] { push_thread(&info1); }); + auto t2 = new sched::thread([&] { push_thread(&info2); }); + auto t3 = new sched::thread([&] { push_thread(&info3); }); + auto tp = new sched::thread([&] { pop_thread(&infop); }); + tp->start(); + t1->start(); + t2->start(); + t3->start(); + t1->join(); + t2->join(); + t3->join(); + tp->join(); + debug(fmt("sum should be %d") % ((len-1)*len/2 * 3)); + delete t1; + delete t2; + delete t3; + delete tp; + delete[] items1; + delete[] items2; + delete[] items3; debug("lockfree MPSC queue tests succeeded"); } };