File: spinlock_tests.cpp

package info (click to toggle)
intel-compute-runtime 22.43.24595.41-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 57,740 kB
  • sloc: cpp: 631,142; lisp: 3,515; sh: 470; makefile: 76; python: 21
file content (69 lines) | stat: -rw-r--r-- 1,822 bytes parent folder | download | duplicates (3)
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
/*
 * Copyright (C) 2018-2021 Intel Corporation
 *
 * SPDX-License-Identifier: MIT
 *
 */

#include "shared/source/utilities/spinlock.h"

#include "gtest/gtest.h"

#include <atomic>
#include <mutex>
#include <thread>

using namespace NEO;

TEST(SpinLockTest, givenTwoThreadsThenVerifyThatTheySynchronizeWithSpinLock) {
    std::atomic<bool> threadStarted(false);
    std::atomic<bool> threadFinished(false);
    SpinLock spinLock;
    int sharedCount = 0;

    // Initially acquire spin lock so the worker thread will wait
    std::unique_lock<SpinLock> lock1{spinLock};

    // Start worker thread
    std::thread workerThread([&]() {
        threadStarted = true;
        std::unique_lock<SpinLock> lock2{spinLock};
        sharedCount++;
        EXPECT_EQ(2, sharedCount);
        lock2.unlock();
        threadFinished = true;
    });

    // Wait till worker thread is started
    while (!threadStarted)
        ;
    sharedCount++;
    EXPECT_EQ(1, sharedCount);

    // Release spin lock thus allowing worker thread to proceed
    lock1.unlock();

    // Wait till worker thread finishes
    while (!threadFinished)
        ;
    EXPECT_EQ(2, sharedCount);
    workerThread.join();
}

TEST(SpinLockTest, givenSpinLockThenAttemptedLockingWorks) {
    SpinLock spinLock;
    auto workerThreadFunction = [&spinLock](bool expectedLockAcquired) {
        std::unique_lock<SpinLock> lock{spinLock, std::defer_lock};
        auto lockAcquired = lock.try_lock();
        EXPECT_EQ(expectedLockAcquired, lockAcquired);
    };

    // Expect locking to fail when lock is already taken
    std::unique_lock<SpinLock> lock{spinLock};
    std::thread workerThread1(workerThreadFunction, false);
    workerThread1.join();

    lock.unlock();
    std::thread workerThread2(workerThreadFunction, true);
    workerThread2.join();
}