diff options
| author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 | 
|---|---|---|
| committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 | 
| commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
| tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/system/mutex_ut.cpp | |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/system/mutex_ut.cpp')
| -rw-r--r-- | util/system/mutex_ut.cpp | 129 | 
1 files changed, 129 insertions, 0 deletions
| diff --git a/util/system/mutex_ut.cpp b/util/system/mutex_ut.cpp new file mode 100644 index 00000000000..c8d7caafa1a --- /dev/null +++ b/util/system/mutex_ut.cpp @@ -0,0 +1,129 @@ +#include "mutex.h" +#include "atomic.h" + +#include <library/cpp/testing/unittest/registar.h> + +#include <util/thread/pool.h> +#include <util/random/random.h> + +class TMutexTest: public TTestBase { +    UNIT_TEST_SUITE(TMutexTest); +    UNIT_TEST(TestBasics) +    UNIT_TEST(TestFake) +    UNIT_TEST(TestRecursive) +    UNIT_TEST_SUITE_END(); + +    struct TSharedData { +        TSharedData() +            : sharedCounter(0) +            , failed(false) +        { +        } + +        volatile ui32 sharedCounter; +        TMutex mutex; +        TFakeMutex fakeMutex; + +        bool failed; +    }; + +    class TThreadTask: public IObjectInQueue { +    public: +        using PFunc = void (TThreadTask::*)(void); + +        TThreadTask(PFunc func, TSharedData& data, size_t id) +            : Func_(func) +            , Data_(data) +            , Id_(id) +        { +        } + +        void Process(void*) override { +            THolder<TThreadTask> This(this); + +            (this->*Func_)(); +        } + +#define FAIL_ASSERT(cond)    \ +    if (!(cond)) {           \ +        Data_.failed = true; \ +    } +        void RunBasics() { +            Data_.mutex.Acquire(); + +            ui32 oldCounter = ui32(Data_.sharedCounter + Id_); +            Data_.sharedCounter = oldCounter; +            usleep(10 + RandomNumber<ui32>() % 10); +            FAIL_ASSERT(Data_.sharedCounter == oldCounter); + +            Data_.mutex.Release(); +        } + +        void RunFakeMutex() { +            bool res = Data_.fakeMutex.TryAcquire(); +            FAIL_ASSERT(res); +        } + +        void RunRecursiveMutex() { +            for (size_t i = 0; i < Id_ + 1; ++i) { +                Data_.mutex.Acquire(); +                ++Data_.sharedCounter; +                usleep(1); +            } +            FAIL_ASSERT(Data_.sharedCounter == Id_ + 1); + +            bool res = Data_.mutex.TryAcquire(); +            FAIL_ASSERT(res); +            Data_.mutex.Release(); + +            for (size_t i = 0; i < Id_; ++i) { +                --Data_.sharedCounter; +                Data_.mutex.Release(); +            } +            FAIL_ASSERT(Data_.sharedCounter == 1); +            --Data_.sharedCounter; +            Data_.mutex.Release(); +        } + +#undef FAIL_ASSERT + +    private: +        PFunc Func_; +        TSharedData& Data_; +        size_t Id_; +    }; + +private: +#define RUN_CYCLE(what, count)                                              \ +    Q_.Start(count);                                                        \ +    for (size_t i = 0; i < count; ++i) {                                    \ +        UNIT_ASSERT(Q_.Add(new TThreadTask(&TThreadTask::what, Data_, i))); \ +    }                                                                       \ +    Q_.Stop();                                                              \ +    bool b = Data_.failed;                                                  \ +    Data_.failed = false;                                                   \ +    UNIT_ASSERT(!b); + +    void TestBasics() { +        RUN_CYCLE(RunBasics, 5); + +        UNIT_ASSERT(Data_.sharedCounter == 10); +        Data_.sharedCounter = 0; +    } + +    void TestFake() { +        RUN_CYCLE(RunFakeMutex, 3); +    } + +    void TestRecursive() { +        RUN_CYCLE(RunRecursiveMutex, 4); +    } + +#undef RUN_CYCLE + +private: +    TSharedData Data_; +    TThreadPool Q_; +}; + +UNIT_TEST_SUITE_REGISTRATION(TMutexTest) | 
