gem5 v24.0.0.0
Loading...
Searching...
No Matches
process.cc
Go to the documentation of this file.
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
29
30#include "systemc/core/event.hh"
31#include "systemc/core/port.hh"
38
39namespace sc_gem5
40{
41
47
53
54template <typename T>
56{
57 public:
58 T t;
59 void throw_it() override { throw t; }
60};
61
64
65
66void
67Process::forEachKid(const std::function<void(Process *)> &work)
68{
69 for (auto &kid: get_child_objects()) {
70 Process *p_kid = dynamic_cast<Process *>(kid);
71 if (p_kid)
72 work(p_kid);
73 }
74}
75
76void
77Process::suspend(bool inc_kids)
78{
79 if (inc_kids)
80 forEachKid([](Process *p) { p->suspend(true); });
81
82 if (!_suspended && !_terminated) {
83 _suspended = true;
85
87 scheduler.current() == this) {
88 // This isn't in the spec, but Accellera says that a thread that
89 // self suspends should be marked ready immediately when it's
90 // resumed.
91 _suspendedReady = true;
93 }
94 }
95}
96
97void
98Process::resume(bool inc_kids)
99{
100 if (inc_kids)
101 forEachKid([](Process *p) { p->resume(true); });
102
103 if (_suspended && !_terminated) {
104 _suspended = false;
105 if (_suspendedReady)
106 scheduler.resume(this);
107 _suspendedReady = false;
108 }
109}
110
111void
112Process::disable(bool inc_kids)
113{
114 if (inc_kids)
115 forEachKid([](Process *p) { p->disable(true); });
116
119 std::string message("attempt to disable a thread with timeout wait: ");
120 message += name();
122 message.c_str());
123 }
124
125 if (!_terminated)
126 _disabled = true;
127}
128
129void
130Process::enable(bool inc_kids)
131{
132
133 if (inc_kids)
134 forEachKid([](Process *p) { p->enable(true); });
135
136 if (!_terminated)
137 _disabled = false;
138}
139
140void
141Process::kill(bool inc_kids)
142{
145 name());
146 }
147
148 // Propogate the kill to our children no matter what happens to us.
149 if (inc_kids)
150 forEachKid([](Process *p) { p->kill(true); });
151
152 // If we're unwinding or terminated, ignore the kill request.
154 return;
155
156 // Update our state.
157 terminate();
158 _isUnwinding = true;
159
160 // Make sure this process isn't marked ready
161 popListNode();
162
163 // Inject the kill exception into this process if it's started.
164 if (!_needsStart)
166}
167
168void
169Process::reset(bool inc_kids)
170{
173 name());
174 }
175
176 // Propogate the reset to our children no matter what happens to us.
177 if (inc_kids)
178 forEachKid([](Process *p) { p->reset(true); });
179
180 // If we're already unwinding or terminated, ignore the reset request.
182 return;
183
184 // Clear suspended ready since we're about to run regardless.
185 _suspendedReady = false;
186
188
189 if (_needsStart) {
190 scheduler.runNow(this);
191 } else {
192 _isUnwinding = true;
194 }
195}
196
197void
199{
202
203 if (inc_kids)
204 forEachKid([&exc](Process *p) { p->throw_it(exc, true); });
205
206 if (_needsStart || _terminated ||
209 return;
210 }
211
212 injectException(exc);
213}
214
215void
221
222void
224{
225 if (inc_kids)
226 forEachKid([](Process *p) { p->syncResetOn(true); });
227
228 _syncReset = true;
229}
230
231void
233{
234 if (inc_kids)
235 forEachKid([](Process *p) { p->syncResetOff(true); });
236
237 _syncReset = false;
238}
239
240void
241Process::signalReset(bool set, bool sync)
242{
243 if (set) {
244 waitCount(0);
245 if (sync) {
247 } else {
250 clearDynamic();
251 scheduler.runNext(this);
252 }
253 } else {
254 if (sync)
256 else
258 }
259}
260
261void
263{
264 bool reset;
265 do {
266 reset = false;
267 try {
268 func->call();
269 } catch(ScHalt) {
270 std::cout << "Terminating process " << name() << std::endl;
271 } catch(const ::sc_core::sc_unwind_exception &exc) {
272 reset = exc.is_reset();
273 _isUnwinding = false;
274 } catch (...) {
275 throw;
276 }
277 } while (reset);
278 needsStart(true);
279}
280
281void
286
287void
296
297void
299{
300 resets.push_back(reset);
301}
302
303void
309
310void
316
317void
319{
320 // A process is considered timed_out only if it was also waiting for an
321 // event but got a timeout instead.
322 _timedOut = (dynamicSensitivity != nullptr);
323
324 setDynamic(nullptr);
325 if (disabled())
326 return;
327
328 ready();
329}
330
331void
333{
334 if (_waitCount) {
335 _waitCount--;
336 return;
337 }
338
339 // If there's a dynamic sensitivity and this wasn't it, ignore.
341 dynamicSensitivity != s) {
342 return;
343 }
344
345 _timedOut = false;
346 // This sensitivity should already be cleared by this point, or the event
347 // which triggered it will take care of it.
348 delete dynamicSensitivity;
349 dynamicSensitivity = nullptr;
351 ready();
352}
353
354void
356{
357 if (disabled())
358 return;
359 if (suspended())
360 _suspendedReady = true;
361 else if (!scheduled())
362 scheduler.ready(this);
363}
364
365void
367{
368 if (report) {
369 _lastReport = std::unique_ptr<::sc_core::sc_report>(
370 new ::sc_core::sc_report(*report));
371 } else {
372 _lastReport = nullptr;
373 }
374}
375
377
378Process::Process(const char *name, ProcessFuncWrapper *func, bool internal) :
379 ::sc_core::sc_process_b(name), excWrapper(nullptr),
380 timeoutEvent([this]() { this->timeout(); }),
381 func(func), _internal(internal), _timedOut(false), _dontInitialize(false),
382 _needsStart(true), _isUnwinding(false), _terminated(false),
383 _scheduled(false), _suspended(false), _disabled(false),
384 _syncReset(false), syncResetCount(0), asyncResetCount(0), _waitCount(0),
385 refCount(0), stackSize(gem5::Fiber::DefaultStackSize),
386 dynamicSensitivity(nullptr)
387{
388 _dynamic =
391 _newest = this;
392}
393
394void
396{
397 _terminated = true;
398 _suspendedReady = false;
399 _suspended = false;
400 _syncReset = false;
401 clearDynamic();
403 for (auto s: staticSensitivities) {
404 s->clear();
405 delete s;
406 }
407 staticSensitivities.clear();
408
410
411 for (auto jw: joinWaiters)
412 jw->signal();
413 joinWaiters.clear();
414}
415
417
418void
420{
421 p->throw_it(exc, inc_kids);
422}
423
424void
425newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v)
426{
427 Port *port = Port::fromPort(pb);
428 port->addReset(new Reset(p, s, v));
429}
430
431void
432newReset(const sc_core::sc_signal_in_if<bool> *sig, Process *p, bool s, bool v)
433{
434 Reset *reset = new Reset(p, s, v);
435 if (!reset->install(sig))
436 delete reset;
437}
438
439} // namespace sc_gem5
const char * name() const
Definition sc_object.cc:44
virtual const std::vector< sc_object * > & get_child_objects() const
Definition sc_object.cc:68
void addReset(Reset *reset)
Definition port.cc:85
static Port * fromPort(const ::sc_core::sc_port_base *pb)
Definition port.hh:121
virtual::sc_core::sc_curr_proc_kind procKind() const =0
static Process * _newest
Definition process.hh:147
ScEvent timeoutEvent
Definition process.hh:113
void kill(bool inc_kids)
Definition process.cc:141
void suspend(bool inc_kids)
Definition process.cc:77
void cancelTimeout()
Definition process.cc:304
void forEachKid(const std::function< void(Process *)> &work)
Definition process.cc:67
DynamicSensitivity * dynamicSensitivity
Definition process.hh:196
void resume(bool inc_kids)
Definition process.cc:98
void addReset(Reset *)
Definition process.cc:298
void disable(bool inc_kids)
Definition process.cc:112
std::unique_ptr<::sc_core::sc_report > _lastReport
Definition process.hh:199
void syncResetOn(bool inc_kids)
Definition process.cc:223
std::vector<::sc_core::sc_join * > joinWaiters
Definition process.hh:201
void clearDynamic()
Definition process.hh:110
void satisfySensitivity(Sensitivity *)
Definition process.cc:332
::sc_core::sc_report * lastReport() const
Definition process.cc:376
std::vector< Reset * > resets
Definition process.hh:197
void signalReset(bool set, bool sync)
Definition process.cc:241
void waitCount(int count)
Definition process.hh:138
StaticSensitivities staticSensitivities
Definition process.hh:195
InternalScEvent _resetEvent
Definition process.hh:160
bool suspended() const
Definition process.hh:78
bool disabled() const
Definition process.hh:79
void setTimeout(::sc_core::sc_time t)
Definition process.cc:311
bool scheduled() const
Definition process.hh:73
InternalScEvent _terminatedEvent
Definition process.hh:161
ProcessFuncWrapper * func
Definition process.hh:163
void setDynamic(DynamicSensitivity *)
Definition process.cc:288
void addStatic(StaticSensitivity *)
Definition process.cc:282
Process(const char *name, ProcessFuncWrapper *func, bool internal=false)
Definition process.cc:378
void reset(bool inc_kids)
Definition process.cc:169
void throw_it(ExceptionWrapperBase &exc, bool inc_kids)
Definition process.cc:198
ExceptionWrapperBase * excWrapper
Definition process.hh:91
bool needsStart() const
Definition process.hh:66
void syncResetOff(bool inc_kids)
Definition process.cc:232
void injectException(ExceptionWrapperBase &exc)
Definition process.cc:216
void enable(bool inc_kids)
Definition process.cc:130
void resume(Process *p)
Definition scheduler.cc:216
bool suspend(Process *p)
Definition scheduler.cc:235
void deschedule(ScEvent *event)
Definition scheduler.hh:280
void runNext(Process *p)
Definition scheduler.hh:230
void schedule(ScEvent *event, const ::sc_core::sc_time &delay)
Definition scheduler.hh:253
void ready(Process *p)
Definition scheduler.cc:199
Process * current()
Definition scheduler.hh:185
void runNow(Process *p)
Definition scheduler.hh:213
virtual void clear()=0
static const size_t DefaultStackSize
Definition fiber.hh:77
const char SC_ID_THROW_IT_IGNORED_[]
Definition messages.cc:128
const char SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_[]
Definition messages.cc:160
sc_status sc_get_status()
Definition sc_main.cc:172
@ SC_RUNNING
Definition sc_main.hh:87
@ SC_BEFORE_END_OF_ELABORATION
Definition sc_main.hh:84
const char SC_ID_PROCESS_CONTROL_CORNER_CASE_[]
Definition messages.cc:135
const char SC_ID_THROW_IT_WHILE_NOT_RUNNING_[]
Definition messages.cc:163
const char SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_[]
Definition messages.cc:158
bool sc_allow_process_control_corners
BuiltinExceptionWrapper< UnwindExceptionReset > resetException
Definition process.cc:62
void newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v)
Definition process.cc:425
void throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids)
Definition process.cc:419
Scheduler scheduler
Definition scheduler.cc:494
BuiltinExceptionWrapper< UnwindExceptionKill > killException
Definition process.cc:63
#define SC_REPORT_WARNING(msg_type, msg)
#define SC_REPORT_ERROR(msg_type, msg)
void popListNode()
Definition list.hh:51
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0