Hash :
07eb4100
        
        Author :
  
        
        Date :
2023-06-09T21:31:01
        
      
[GlobalMutex] Do not assume the thread conflict happens in tests There isn't a guarantee that threads would always conflict with each other, so the assertion here would fail randomly. Overall: https://ci.chromium.org/ui/test/chromium/ninja%3A%2F%2Fthird_party%2Fangle%2Fsrc%2Ftests%3Aangle_unittests%2FGlobalMutexTest.ScopedOptionalGlobalMutexLockDisabled?q=+V%3Atest_suite%3Dangle_unittests+ Examples: https://chromium-swarm.appspot.com/task?id=623bb4e76b382911 https://chromium-swarm.appspot.com/task?id=62ba96ea430b8811 Fixed: angleproject:8194 Change-Id: Iaf2e5371a162d21f565e72f96d487d12c69f88c3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4606236 Auto-Submit: Zijie He <zijiehe@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
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 93 94 95 96 97 98 99 100 101 102 103 104
//
// Copyright 2023 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// GlobalMutex_unittest:
//   Tests of the Scoped<*>GlobalMutexLock classes
//
#include <gtest/gtest.h>
#include "libANGLE/GlobalMutex.h"
namespace
{
template <class ScopedGlobalLockT, class... Args>
void runBasicGlobalMutexTest(bool expectToPass, Args &&...args)
{
    constexpr size_t kThreadCount    = 16;
    constexpr size_t kIterationCount = 50'000;
    std::array<std::thread, kThreadCount> threads;
    std::mutex mutex;
    std::condition_variable condVar;
    size_t readyCount = 0;
    std::atomic<size_t> testVar;
    for (size_t i = 0; i < kThreadCount; ++i)
    {
        threads[i] = std::thread([&]() {
            {
                std::unique_lock<std::mutex> lock(mutex);
                ++readyCount;
                if (readyCount < kThreadCount)
                {
                    condVar.wait(lock, [&]() { return readyCount == kThreadCount; });
                }
                else
                {
                    condVar.notify_all();
                }
            }
            for (size_t j = 0; j < kIterationCount; ++j)
            {
                ScopedGlobalLockT lock(std::forward<Args>(args)...);
                const int local    = testVar.load(std::memory_order_relaxed);
                const int newValue = local + 1;
                testVar.store(newValue, std::memory_order_relaxed);
            }
        });
    }
    for (size_t i = 0; i < kThreadCount; ++i)
    {
        threads[i].join();
    }
    if (expectToPass)
    {
        EXPECT_EQ(testVar.load(), kThreadCount * kIterationCount);
    }
    else
    {
        EXPECT_LE(testVar.load(), kThreadCount * kIterationCount);
    }
}
// Tests basic usage of ScopedGlobalMutexLock.
TEST(GlobalMutexTest, ScopedGlobalMutexLock)
{
    runBasicGlobalMutexTest<egl::ScopedGlobalMutexLock>(true);
}
// Tests basic usage of ScopedOptionalGlobalMutexLock (Enabled).
TEST(GlobalMutexTest, ScopedOptionalGlobalMutexLockEnabled)
{
    runBasicGlobalMutexTest<egl::ScopedOptionalGlobalMutexLock>(true, true);
}
// Tests basic usage of ScopedOptionalGlobalMutexLock (Disabled).
TEST(GlobalMutexTest, ScopedOptionalGlobalMutexLockDisabled)
{
    runBasicGlobalMutexTest<egl::ScopedOptionalGlobalMutexLock>(false, false);
}
#if defined(ANGLE_ENABLE_GLOBAL_MUTEX_RECURSION)
// Tests that ScopedGlobalMutexLock can be recursively locked.
TEST(GlobalMutexTest, RecursiveScopedGlobalMutexLock)
{
    egl::ScopedGlobalMutexLock lock;
    egl::ScopedGlobalMutexLock lock2;
}
// Tests that ScopedOptionalGlobalMutexLock can be recursively locked.
TEST(GlobalMutexTest, RecursiveScopedOptionalGlobalMutexLock)
{
    egl::ScopedOptionalGlobalMutexLock lock(true);
    egl::ScopedOptionalGlobalMutexLock lock2(true);
}
#endif
}  // anonymous namespace