Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/test_utils/MultiThreadSteps.h
1693 views
1
//
2
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
// EGLMultiContextTest.cpp:
7
// Synchronization help for tests that use multiple threads.
8
9
#include <atomic>
10
#include <condition_variable>
11
#include <mutex>
12
#include <thread>
13
14
namespace
15
{
16
17
// The following class is used by tests that need multiple threads that coordinate their actions
18
// via an enum of "steps". This enum is the template type E. The enum must have at least the
19
// following values:
20
//
21
// - Finish This value indicates that one thread has finished its last step and is cleaning up.
22
// The other thread waits for this before it does its last step and cleans up.
23
// - Abort This value indicates that one thread encountered a GL error and has exited. This
24
// will cause the other thread (that is waiting for a different step) to also abort.
25
//
26
// This class is RAII. It is declared at the top of a thread, and will be deconstructed at the end
27
// of the thread's outer block. If the thread encounters a GL error, the deconstructor will abort
28
// the other thread using the E:Abort step.
29
template <typename E>
30
class ThreadSynchronization
31
{
32
public:
33
ThreadSynchronization(E *currentStep, std::mutex *mutex, std::condition_variable *condVar)
34
: mCurrentStep(currentStep), mMutex(mutex), mCondVar(condVar)
35
{}
36
~ThreadSynchronization()
37
{
38
bool isAborting = false;
39
{
40
// If the other thread isn't finished, cause it to abort.
41
std::unique_lock<std::mutex> lock(*mMutex);
42
isAborting = *mCurrentStep != E::Finish;
43
44
if (isAborting)
45
{
46
*mCurrentStep = E::Abort;
47
}
48
}
49
mCondVar->notify_all();
50
}
51
52
// Helper functions to synchronize the threads so that the operations are executed in the
53
// specific order the test is written for.
54
bool waitForStep(E waitStep)
55
{
56
std::unique_lock<std::mutex> lock(*mMutex);
57
while (*mCurrentStep != waitStep)
58
{
59
// If necessary, abort execution as the other thread has encountered a GL error.
60
if (*mCurrentStep == E::Abort)
61
{
62
return false;
63
}
64
mCondVar->wait(lock);
65
}
66
67
return true;
68
}
69
70
void nextStep(E newStep)
71
{
72
{
73
std::unique_lock<std::mutex> lock(*mMutex);
74
*mCurrentStep = newStep;
75
}
76
mCondVar->notify_one();
77
}
78
79
private:
80
E *mCurrentStep;
81
std::mutex *mMutex;
82
std::condition_variable *mCondVar;
83
};
84
} // anonymous namespace
85
86