xref: /aosp_15_r20/external/swiftshader/src/Vulkan/Debug/Thread.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "Thread.hpp"
16*03ce13f7SAndroid Build Coastguard Worker 
17*03ce13f7SAndroid Build Coastguard Worker #include "Context.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "EventListener.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "File.hpp"
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker namespace vk {
22*03ce13f7SAndroid Build Coastguard Worker namespace dbg {
23*03ce13f7SAndroid Build Coastguard Worker 
Thread(ID id,Context * ctx)24*03ce13f7SAndroid Build Coastguard Worker Thread::Thread(ID id, Context *ctx)
25*03ce13f7SAndroid Build Coastguard Worker     : id(id)
26*03ce13f7SAndroid Build Coastguard Worker     , ctx(ctx)
27*03ce13f7SAndroid Build Coastguard Worker {}
28*03ce13f7SAndroid Build Coastguard Worker 
setName(const std::string & name)29*03ce13f7SAndroid Build Coastguard Worker void Thread::setName(const std::string &name)
30*03ce13f7SAndroid Build Coastguard Worker {
31*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
32*03ce13f7SAndroid Build Coastguard Worker 	name_ = name;
33*03ce13f7SAndroid Build Coastguard Worker }
34*03ce13f7SAndroid Build Coastguard Worker 
name() const35*03ce13f7SAndroid Build Coastguard Worker std::string Thread::name() const
36*03ce13f7SAndroid Build Coastguard Worker {
37*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
38*03ce13f7SAndroid Build Coastguard Worker 	return name_;
39*03ce13f7SAndroid Build Coastguard Worker }
40*03ce13f7SAndroid Build Coastguard Worker 
onLocationUpdate(marl::lock & lock)41*03ce13f7SAndroid Build Coastguard Worker void Thread::onLocationUpdate(marl::lock &lock)
42*03ce13f7SAndroid Build Coastguard Worker {
43*03ce13f7SAndroid Build Coastguard Worker 	auto location = frames.back()->location;
44*03ce13f7SAndroid Build Coastguard Worker 
45*03ce13f7SAndroid Build Coastguard Worker 	if(state_ == State::Running)
46*03ce13f7SAndroid Build Coastguard Worker 	{
47*03ce13f7SAndroid Build Coastguard Worker 		if(location.file->hasBreakpoint(location.line))
48*03ce13f7SAndroid Build Coastguard Worker 		{
49*03ce13f7SAndroid Build Coastguard Worker 			ctx->serverEventBroadcast()->onLineBreakpointHit(id);
50*03ce13f7SAndroid Build Coastguard Worker 			state_ = State::Paused;
51*03ce13f7SAndroid Build Coastguard Worker 		}
52*03ce13f7SAndroid Build Coastguard Worker 	}
53*03ce13f7SAndroid Build Coastguard Worker 
54*03ce13f7SAndroid Build Coastguard Worker 	switch(state_)
55*03ce13f7SAndroid Build Coastguard Worker 	{
56*03ce13f7SAndroid Build Coastguard Worker 	case State::Paused:
57*03ce13f7SAndroid Build Coastguard Worker 		lock.wait(stateCV, [this]() REQUIRES(mutex) { return state_ != State::Paused; });
58*03ce13f7SAndroid Build Coastguard Worker 		break;
59*03ce13f7SAndroid Build Coastguard Worker 
60*03ce13f7SAndroid Build Coastguard Worker 	case State::Stepping:
61*03ce13f7SAndroid Build Coastguard Worker 		{
62*03ce13f7SAndroid Build Coastguard Worker 			bool pause = false;
63*03ce13f7SAndroid Build Coastguard Worker 
64*03ce13f7SAndroid Build Coastguard Worker 			{
65*03ce13f7SAndroid Build Coastguard Worker 				auto frame = pauseAtFrame.lock();
66*03ce13f7SAndroid Build Coastguard Worker 				pause = !frame;             // Pause if there's no pause-at-frame...
67*03ce13f7SAndroid Build Coastguard Worker 				if(frame == frames.back())  // ... or if we've reached the pause-at-frame
68*03ce13f7SAndroid Build Coastguard Worker 				{
69*03ce13f7SAndroid Build Coastguard Worker 					pause = true;
70*03ce13f7SAndroid Build Coastguard Worker 					pauseAtFrame.reset();
71*03ce13f7SAndroid Build Coastguard Worker 				}
72*03ce13f7SAndroid Build Coastguard Worker 			}
73*03ce13f7SAndroid Build Coastguard Worker 
74*03ce13f7SAndroid Build Coastguard Worker 			if(pause)
75*03ce13f7SAndroid Build Coastguard Worker 			{
76*03ce13f7SAndroid Build Coastguard Worker 				ctx->serverEventBroadcast()->onThreadStepped(id);
77*03ce13f7SAndroid Build Coastguard Worker 				state_ = State::Paused;
78*03ce13f7SAndroid Build Coastguard Worker 				lock.wait(stateCV, [this]() REQUIRES(mutex) { return state_ != State::Paused; });
79*03ce13f7SAndroid Build Coastguard Worker 			}
80*03ce13f7SAndroid Build Coastguard Worker 		}
81*03ce13f7SAndroid Build Coastguard Worker 		break;
82*03ce13f7SAndroid Build Coastguard Worker 
83*03ce13f7SAndroid Build Coastguard Worker 	case State::Running:
84*03ce13f7SAndroid Build Coastguard Worker 		break;
85*03ce13f7SAndroid Build Coastguard Worker 	}
86*03ce13f7SAndroid Build Coastguard Worker }
87*03ce13f7SAndroid Build Coastguard Worker 
enter(const std::shared_ptr<File> & file,const std::string & function,const UpdateFrame & f)88*03ce13f7SAndroid Build Coastguard Worker void Thread::enter(const std::shared_ptr<File> &file, const std::string &function, const UpdateFrame &f)
89*03ce13f7SAndroid Build Coastguard Worker {
90*03ce13f7SAndroid Build Coastguard Worker 	std::shared_ptr<Frame> frame;
91*03ce13f7SAndroid Build Coastguard Worker 	bool isFunctionBreakpoint;
92*03ce13f7SAndroid Build Coastguard Worker 	{
93*03ce13f7SAndroid Build Coastguard Worker 		auto lock = ctx->lock();
94*03ce13f7SAndroid Build Coastguard Worker 		frame = lock.createFrame(file, function);
95*03ce13f7SAndroid Build Coastguard Worker 		isFunctionBreakpoint = lock.isFunctionBreakpoint(function);
96*03ce13f7SAndroid Build Coastguard Worker 	}
97*03ce13f7SAndroid Build Coastguard Worker 
98*03ce13f7SAndroid Build Coastguard Worker 	{
99*03ce13f7SAndroid Build Coastguard Worker 		marl::lock lock(mutex);
100*03ce13f7SAndroid Build Coastguard Worker 		frames.push_back(frame);
101*03ce13f7SAndroid Build Coastguard Worker 
102*03ce13f7SAndroid Build Coastguard Worker 		if(f) { f(*frame); }
103*03ce13f7SAndroid Build Coastguard Worker 
104*03ce13f7SAndroid Build Coastguard Worker 		if(isFunctionBreakpoint)
105*03ce13f7SAndroid Build Coastguard Worker 		{
106*03ce13f7SAndroid Build Coastguard Worker 			ctx->serverEventBroadcast()->onFunctionBreakpointHit(id);
107*03ce13f7SAndroid Build Coastguard Worker 			state_ = State::Paused;
108*03ce13f7SAndroid Build Coastguard Worker 		}
109*03ce13f7SAndroid Build Coastguard Worker 
110*03ce13f7SAndroid Build Coastguard Worker 		onLocationUpdate(lock);
111*03ce13f7SAndroid Build Coastguard Worker 	}
112*03ce13f7SAndroid Build Coastguard Worker }
113*03ce13f7SAndroid Build Coastguard Worker 
exit(bool isStep)114*03ce13f7SAndroid Build Coastguard Worker void Thread::exit(bool isStep /* = false */)
115*03ce13f7SAndroid Build Coastguard Worker {
116*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
117*03ce13f7SAndroid Build Coastguard Worker 	frames.pop_back();
118*03ce13f7SAndroid Build Coastguard Worker 	if(isStep)
119*03ce13f7SAndroid Build Coastguard Worker 	{
120*03ce13f7SAndroid Build Coastguard Worker 		onLocationUpdate(lock);
121*03ce13f7SAndroid Build Coastguard Worker 	}
122*03ce13f7SAndroid Build Coastguard Worker }
123*03ce13f7SAndroid Build Coastguard Worker 
update(bool isStep,const UpdateFrame & f)124*03ce13f7SAndroid Build Coastguard Worker void Thread::update(bool isStep, const UpdateFrame &f)
125*03ce13f7SAndroid Build Coastguard Worker {
126*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
127*03ce13f7SAndroid Build Coastguard Worker 	auto &frame = *frames.back();
128*03ce13f7SAndroid Build Coastguard Worker 	if(isStep)
129*03ce13f7SAndroid Build Coastguard Worker 	{
130*03ce13f7SAndroid Build Coastguard Worker 		auto oldLocation = frame.location;
131*03ce13f7SAndroid Build Coastguard Worker 		f(frame);
132*03ce13f7SAndroid Build Coastguard Worker 		if(frame.location != oldLocation)
133*03ce13f7SAndroid Build Coastguard Worker 		{
134*03ce13f7SAndroid Build Coastguard Worker 			onLocationUpdate(lock);
135*03ce13f7SAndroid Build Coastguard Worker 		}
136*03ce13f7SAndroid Build Coastguard Worker 	}
137*03ce13f7SAndroid Build Coastguard Worker 	else
138*03ce13f7SAndroid Build Coastguard Worker 	{
139*03ce13f7SAndroid Build Coastguard Worker 		f(frame);
140*03ce13f7SAndroid Build Coastguard Worker 	}
141*03ce13f7SAndroid Build Coastguard Worker }
142*03ce13f7SAndroid Build Coastguard Worker 
frame() const143*03ce13f7SAndroid Build Coastguard Worker Frame Thread::frame() const
144*03ce13f7SAndroid Build Coastguard Worker {
145*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
146*03ce13f7SAndroid Build Coastguard Worker 	return *frames.back();
147*03ce13f7SAndroid Build Coastguard Worker }
148*03ce13f7SAndroid Build Coastguard Worker 
stack() const149*03ce13f7SAndroid Build Coastguard Worker std::vector<Frame> Thread::stack() const
150*03ce13f7SAndroid Build Coastguard Worker {
151*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
152*03ce13f7SAndroid Build Coastguard Worker 	std::vector<Frame> out;
153*03ce13f7SAndroid Build Coastguard Worker 	out.reserve(frames.size());
154*03ce13f7SAndroid Build Coastguard Worker 	for(auto frame : frames)
155*03ce13f7SAndroid Build Coastguard Worker 	{
156*03ce13f7SAndroid Build Coastguard Worker 		out.push_back(*frame);
157*03ce13f7SAndroid Build Coastguard Worker 	}
158*03ce13f7SAndroid Build Coastguard Worker 	return out;
159*03ce13f7SAndroid Build Coastguard Worker }
160*03ce13f7SAndroid Build Coastguard Worker 
depth() const161*03ce13f7SAndroid Build Coastguard Worker size_t Thread::depth() const
162*03ce13f7SAndroid Build Coastguard Worker {
163*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
164*03ce13f7SAndroid Build Coastguard Worker 	return frames.size();
165*03ce13f7SAndroid Build Coastguard Worker }
166*03ce13f7SAndroid Build Coastguard Worker 
state() const167*03ce13f7SAndroid Build Coastguard Worker Thread::State Thread::state() const
168*03ce13f7SAndroid Build Coastguard Worker {
169*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
170*03ce13f7SAndroid Build Coastguard Worker 	return state_;
171*03ce13f7SAndroid Build Coastguard Worker }
172*03ce13f7SAndroid Build Coastguard Worker 
resume()173*03ce13f7SAndroid Build Coastguard Worker void Thread::resume()
174*03ce13f7SAndroid Build Coastguard Worker {
175*03ce13f7SAndroid Build Coastguard Worker 	{
176*03ce13f7SAndroid Build Coastguard Worker 		marl::lock lock(mutex);
177*03ce13f7SAndroid Build Coastguard Worker 		state_ = State::Running;
178*03ce13f7SAndroid Build Coastguard Worker 	}
179*03ce13f7SAndroid Build Coastguard Worker 	stateCV.notify_all();
180*03ce13f7SAndroid Build Coastguard Worker }
181*03ce13f7SAndroid Build Coastguard Worker 
pause()182*03ce13f7SAndroid Build Coastguard Worker void Thread::pause()
183*03ce13f7SAndroid Build Coastguard Worker {
184*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
185*03ce13f7SAndroid Build Coastguard Worker 	state_ = State::Paused;
186*03ce13f7SAndroid Build Coastguard Worker }
187*03ce13f7SAndroid Build Coastguard Worker 
stepIn()188*03ce13f7SAndroid Build Coastguard Worker void Thread::stepIn()
189*03ce13f7SAndroid Build Coastguard Worker {
190*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
191*03ce13f7SAndroid Build Coastguard Worker 	state_ = State::Stepping;
192*03ce13f7SAndroid Build Coastguard Worker 	pauseAtFrame.reset();
193*03ce13f7SAndroid Build Coastguard Worker 	stateCV.notify_all();
194*03ce13f7SAndroid Build Coastguard Worker }
195*03ce13f7SAndroid Build Coastguard Worker 
stepOver()196*03ce13f7SAndroid Build Coastguard Worker void Thread::stepOver()
197*03ce13f7SAndroid Build Coastguard Worker {
198*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
199*03ce13f7SAndroid Build Coastguard Worker 	state_ = State::Stepping;
200*03ce13f7SAndroid Build Coastguard Worker 	pauseAtFrame = frames.back();
201*03ce13f7SAndroid Build Coastguard Worker 	stateCV.notify_all();
202*03ce13f7SAndroid Build Coastguard Worker }
203*03ce13f7SAndroid Build Coastguard Worker 
stepOut()204*03ce13f7SAndroid Build Coastguard Worker void Thread::stepOut()
205*03ce13f7SAndroid Build Coastguard Worker {
206*03ce13f7SAndroid Build Coastguard Worker 	marl::lock lock(mutex);
207*03ce13f7SAndroid Build Coastguard Worker 	state_ = State::Stepping;
208*03ce13f7SAndroid Build Coastguard Worker 	pauseAtFrame = (frames.size() > 1) ? frames[frames.size() - 2] : nullptr;
209*03ce13f7SAndroid Build Coastguard Worker 	stateCV.notify_all();
210*03ce13f7SAndroid Build Coastguard Worker }
211*03ce13f7SAndroid Build Coastguard Worker 
212*03ce13f7SAndroid Build Coastguard Worker }  // namespace dbg
213*03ce13f7SAndroid Build Coastguard Worker }  // namespace vk
214