summaryrefslogtreecommitdiffstats
path: root/library/cpp/threading/queue/basic_ut.cpp
blob: 2db5d6e8e83b53171fd350b0cbd7f6d28ec57984 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <library/cpp/testing/unittest/registar.h>
#include <util/generic/vector.h> 
#include <util/system/thread.h> 
 
#include "ut_helpers.h" 
 
template <typename TQueueType>
class TQueueTestsInSingleThread: public TTestBase { 
private: 
    using TSelf = TQueueTestsInSingleThread<TQueueType>;
    using TLink = TIntrusiveLink; 
 
    UNIT_TEST_SUITE_DEMANGLE(TSelf); 
    UNIT_TEST(OnePushOnePop) 
    UNIT_TEST(OnePushOnePop_Repeat1M) 
    UNIT_TEST(Threads8_Repeat1M_Push1Pop1) 
    UNIT_TEST_SUITE_END(); 
 
public: 
    void OnePushOnePop() { 
        TQueueType queue;
 
        auto popped = queue.Pop(); 
        UNIT_ASSERT_VALUES_EQUAL(popped, nullptr); 
 
        TLink msg; 
        queue.Push(&msg); 
        popped = queue.Pop(); 
        UNIT_ASSERT_VALUES_EQUAL(&msg, popped); 
 
        popped = queue.Pop(); 
        UNIT_ASSERT_VALUES_EQUAL(popped, nullptr); 
    }; 
 
    void OnePushOnePop_Repeat1M() { 
        TQueueType queue;
        TLink msg; 
 
        auto popped = queue.Pop(); 
        UNIT_ASSERT_VALUES_EQUAL(popped, nullptr); 
 
        for (int i = 0; i < 1000000; ++i) { 
            queue.Push(&msg); 
            popped = queue.Pop(); 
            UNIT_ASSERT_VALUES_EQUAL(&msg, popped); 
 
            popped = queue.Pop(); 
            UNIT_ASSERT_VALUES_EQUAL(popped, nullptr); 
        } 
    } 
 
    template <size_t NUMBER_OF_THREADS> 
    void RepeatPush1Pop1_InManyThreads() { 
        class TCycleThread: public ISimpleThread {
        public: 
            void* ThreadProc() override { 
                TQueueType queue;
                TLink msg; 
                auto popped = queue.Pop(); 
                UNIT_ASSERT_VALUES_EQUAL(popped, nullptr); 
 
                for (size_t i = 0; i < 1000000; ++i) { 
                    queue.Push(&msg); 
                    popped = queue.Pop(); 
                    UNIT_ASSERT_VALUES_EQUAL(popped, &msg); 
 
                    popped = queue.Pop(); 
                    UNIT_ASSERT_VALUES_EQUAL(popped, nullptr); 
                } 
                return nullptr; 
            } 
        }; 
 
        TVector<TAutoPtr<TCycleThread>> cyclers;
 
        for (size_t i = 0; i < NUMBER_OF_THREADS; ++i) { 
            cyclers.emplace_back(new TCycleThread); 
            cyclers.back()->Start(); 
        } 
 
        for (size_t i = 0; i < NUMBER_OF_THREADS; ++i) { 
            cyclers[i]->Join(); 
        } 
    } 
 
    void Threads8_Repeat1M_Push1Pop1() { 
        RepeatPush1Pop1_InManyThreads<8>(); 
    } 
}; 
 
REGISTER_TESTS_FOR_ALL_ORDERED_QUEUES(TQueueTestsInSingleThread); 
REGISTER_TESTS_FOR_ALL_UNORDERED_QUEUES(TQueueTestsInSingleThread)