gem5  v20.1.0.0
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 
28 #include "systemc/core/process.hh"
29 
30 #include "systemc/core/event.hh"
31 #include "systemc/core/port.hh"
38 
39 namespace sc_gem5
40 {
41 
43 {
44  public:
46 };
47 
49 {
50  public:
52 };
53 
54 template <typename T>
56 {
57  public:
58  T t;
59  void throw_it() override { throw t; }
60 };
61 
64 
65 
66 void
67 Process::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 
76 void
77 Process::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;
92  scheduler.yield();
93  }
94  }
95 }
96 
97 void
98 Process::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 
111 void
112 Process::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 
129 void
130 Process::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 
140 void
141 Process::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.
153  if (_isUnwinding || _terminated)
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 
168 void
169 Process::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.
181  if (_isUnwinding || _terminated)
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 
197 void
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 
215 void
217 {
218  excWrapper = &exc;
219  scheduler.runNow(this);
220 };
221 
222 void
223 Process::syncResetOn(bool inc_kids)
224 {
225  if (inc_kids)
226  forEachKid([](Process *p) { p->syncResetOn(true); });
227 
228  _syncReset = true;
229 }
230 
231 void
232 Process::syncResetOff(bool inc_kids)
233 {
234  if (inc_kids)
235  forEachKid([](Process *p) { p->syncResetOff(true); });
236 
237  _syncReset = false;
238 }
239 
240 void
241 Process::signalReset(bool set, bool sync)
242 {
243  if (set) {
244  waitCount(0);
245  if (sync) {
246  syncResetCount++;
247  } else {
248  asyncResetCount++;
249  cancelTimeout();
250  clearDynamic();
251  scheduler.runNext(this);
252  }
253  } else {
254  if (sync)
255  syncResetCount--;
256  else
257  asyncResetCount--;
258  }
259 }
260 
261 void
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 
281 void
283 {
284  staticSensitivities.push_back(s);
285 }
286 
287 void
289 {
290  if (dynamicSensitivity) {
292  delete dynamicSensitivity;
293  }
295 }
296 
297 void
299 {
300  resets.push_back(reset);
301 }
302 
303 void
305 {
306  if (timeoutEvent.scheduled())
308 }
309 
310 void
312 {
313  cancelTimeout();
315 }
316 
317 void
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 
331 void
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;
350  cancelTimeout();
351  ready();
352 }
353 
354 void
356 {
357  if (disabled())
358  return;
359  if (suspended())
360  _suspendedReady = true;
361  else if (!scheduled())
362  scheduler.ready(this);
363 }
364 
365 void
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 
378 Process::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(::Fiber::DefaultStackSize),
386  dynamicSensitivity(nullptr)
387 {
388  _dynamic =
391  _newest = this;
392 }
393 
394 void
396 {
397  _terminated = true;
398  _suspendedReady = false;
399  _suspended = false;
400  _syncReset = false;
401  clearDynamic();
402  cancelTimeout();
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 
418 void
420 {
421  p->throw_it(exc, inc_kids);
422 }
423 
424 void
425 newReset(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 
431 void
433 {
434  Reset *reset = new Reset(p, s, v);
435  if (!reset->install(sig))
436  delete reset;
437 }
438 
439 } // namespace sc_gem5
sc_gem5::Process::forEachKid
void forEachKid(const std::function< void(Process *)> &work)
Definition: process.cc:67
port.hh
sc_core::sc_port_base
Definition: sc_port.hh:74
sc_gem5::Process::scheduled
bool scheduled() const
Definition: process.hh:73
sc_gem5::Process::_needsStart
bool _needsStart
Definition: process.hh:172
sc_gem5::Scheduler::resume
void resume(Process *p)
Definition: scheduler.cc:217
sc_gem5::BuiltinExceptionWrapper::t
T t
Definition: process.cc:58
sc_core::sc_signal_in_if< bool >
Definition: sc_signal_in_if.hh:74
sc_core::sc_get_status
sc_status sc_get_status()
Definition: sc_main.cc:173
sc_gem5::Process::timeout
void timeout()
Definition: process.cc:318
sc_gem5::UnwindExceptionKill
Definition: process.cc:48
sc_gem5::ProcessFuncWrapper
Definition: sc_process_handle.hh:43
sc_core::sc_object::get_child_objects
virtual const std::vector< sc_object * > & get_child_objects() const
Definition: sc_object.cc:68
sc_gem5::Process::_syncReset
bool _syncReset
Definition: process.hh:184
sc_core::SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_
const char SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_[]
Definition: messages.cc:160
sc_gem5::Scheduler::deschedule
void deschedule(ScEvent *event)
Definition: scheduler.hh:263
sc_gem5::Process::injectException
void injectException(ExceptionWrapperBase &exc)
Definition: process.cc:216
sc_gem5::Process::throw_it
void throw_it(ExceptionWrapperBase &exc, bool inc_kids)
Definition: process.cc:198
sc_core
Definition: messages.cc:31
sc_gem5::Process::lastReport
::sc_core::sc_report * lastReport() const
Definition: process.cc:376
sc_gem5::killException
BuiltinExceptionWrapper< UnwindExceptionKill > killException
Definition: process.cc:63
sc_gem5::Process::setDynamic
void setDynamic(DynamicSensitivity *)
Definition: process.cc:288
sc_core::sc_unwind_exception::_isReset
bool _isReset
Definition: sc_process_handle.hh:112
sc_gem5::Process::resets
std::vector< Reset * > resets
Definition: process.hh:197
sc_gem5::Process::_terminatedEvent
InternalScEvent _terminatedEvent
Definition: process.hh:161
sc_core::SC_BEFORE_END_OF_ELABORATION
@ SC_BEFORE_END_OF_ELABORATION
Definition: sc_main.hh:84
sc_gem5::Reset
Definition: process.hh:206
sc_gem5::Process::reset
void reset(bool inc_kids)
Definition: process.cc:169
Stats::reset
void reset()
Definition: statistics.cc:569
sc_gem5::Process::_disabled
bool _disabled
Definition: process.hh:182
sc_gem5::Process::dynamicSensitivity
DynamicSensitivity * dynamicSensitivity
Definition: process.hh:196
sc_core::SC_ID_THROW_IT_WHILE_NOT_RUNNING_
const char SC_ID_THROW_IT_WHILE_NOT_RUNNING_[]
Definition: messages.cc:163
sc_gem5::Process::cancelTimeout
void cancelTimeout()
Definition: process.cc:304
sc_core::SC_ID_THROW_IT_IGNORED_
const char SC_ID_THROW_IT_IGNORED_[]
Definition: messages.cc:128
sc_gem5::Process::run
void run()
Definition: process.cc:262
sc_gem5::Process::enable
void enable(bool inc_kids)
Definition: process.cc:130
sc_gem5::Process::setTimeout
void setTimeout(::sc_core::sc_time t)
Definition: process.cc:311
sc_gem5::Scheduler::ready
void ready(Process *p)
Definition: scheduler.cc:200
sc_gem5::Process::timeoutEvent
ScEvent timeoutEvent
Definition: process.hh:113
sc_gem5::Process::kill
void kill(bool inc_kids)
Definition: process.cc:141
sc_gem5::Port::fromPort
static Port * fromPort(const ::sc_core::sc_port_base *pb)
Definition: port.hh:121
sc_gem5::Process::excWrapper
ExceptionWrapperBase * excWrapper
Definition: process.hh:91
sc_gem5::Process::_waitCount
int _waitCount
Definition: process.hh:189
Fiber::DefaultStackSize
const static size_t DefaultStackSize
Definition: fiber.hh:68
SC_REPORT_ERROR
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report_handler.hh:127
sc_gem5::DynamicSensitivity
Definition: sensitivity.hh:96
sc_gem5::ListNode::popListNode
void popListNode()
Definition: list.hh:51
sc_core::sc_unwind_exception
Definition: sc_process_handle.hh:98
sc_gem5::Process::staticSensitivities
StaticSensitivities staticSensitivities
Definition: process.hh:195
sc_gem5::StaticSensitivity
Definition: sensitivity.hh:111
sc_gem5::Scheduler::runNow
void runNow(Process *p)
Definition: scheduler.hh:198
sc_main.hh
sc_core::sc_time
Definition: sc_time.hh:49
sc_gem5::ExceptionWrapperBase
Definition: sc_process_handle.hh:61
sc_gem5::Scheduler::yield
void yield()
Definition: scheduler.cc:161
sc_gem5::Process::disabled
bool disabled() const
Definition: process.hh:79
sc_core::SC_METHOD_PROC_
@ SC_METHOD_PROC_
Definition: sc_process_handle.hh:87
sc_gem5::ScHalt
Definition: process.hh:56
sc_gem5::Process::Process
Process(const char *name, ProcessFuncWrapper *func, bool internal=false)
Definition: process.cc:378
sc_gem5::Process::_suspended
bool _suspended
Definition: process.hh:180
messages.hh
sc_gem5::Process::suspend
void suspend(bool inc_kids)
Definition: process.cc:77
sc_gem5::Process::addStatic
void addStatic(StaticSensitivity *)
Definition: process.cc:282
sc_gem5::Process::satisfySensitivity
void satisfySensitivity(Sensitivity *)
Definition: process.cc:332
sc_gem5::Process::syncResetOff
void syncResetOff(bool inc_kids)
Definition: process.cc:232
sc_gem5::UnwindExceptionKill::UnwindExceptionKill
UnwindExceptionKill()
Definition: process.cc:51
sc_gem5::Scheduler::suspend
bool suspend(Process *p)
Definition: scheduler.cc:236
sc_gem5::newReset
void newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v)
Definition: process.cc:425
sc_gem5::Process
Definition: process.hh:62
sc_gem5::Process::terminate
void terminate()
Definition: process.cc:395
name
const std::string & name()
Definition: trace.cc:50
sc_gem5::BuiltinExceptionWrapper
Definition: process.cc:55
sc_gem5::Process::syncResetCount
int syncResetCount
Definition: process.hh:186
sc_gem5::ScEvent::scheduled
bool scheduled()
Definition: sched_event.hh:78
sc_core::sc_report
Definition: sc_report.hh:60
process.hh
sc_core::sc_event::notify
void notify()
Definition: sc_event.cc:337
sc_gem5::Process::_suspendedReady
bool _suspendedReady
Definition: process.hh:181
sc_gem5::BuiltinExceptionWrapper::throw_it
void throw_it() override
Definition: process.cc:59
SC_REPORT_WARNING
#define SC_REPORT_WARNING(msg_type, msg)
Definition: sc_report_handler.hh:123
sc_core::SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_
const char SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_[]
Definition: messages.cc:158
sc_gem5::Process::syncResetOn
void syncResetOn(bool inc_kids)
Definition: process.cc:223
sc_gem5::UnwindExceptionReset
Definition: process.cc:42
sc_report_handler.hh
sc_process_handle.hh
sc_gem5::Scheduler::current
Process * current()
Definition: scheduler.hh:170
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
sc_gem5::Scheduler::runNext
void runNext(Process *p)
Definition: scheduler.hh:215
sc_gem5::Port::addReset
void addReset(Reset *reset)
Definition: port.cc:85
sc_gem5::Process::_lastReport
std::unique_ptr<::sc_core::sc_report > _lastReport
Definition: process.hh:199
sc_core::sc_object::name
const char * name() const
Definition: sc_object.cc:44
sc_gem5::throw_it_wrapper
void throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids)
Definition: process.cc:419
sc_gem5::Process::suspended
bool suspended() const
Definition: process.hh:78
sc_gem5::UnwindExceptionReset::UnwindExceptionReset
UnwindExceptionReset()
Definition: process.cc:45
sc_gem5::Process::disable
void disable(bool inc_kids)
Definition: process.cc:112
sc_gem5::resetException
BuiltinExceptionWrapper< UnwindExceptionReset > resetException
Definition: process.cc:62
sc_gem5::Process::_resetEvent
InternalScEvent _resetEvent
Definition: process.hh:160
sc_gem5::Port
Definition: port.hh:50
sc_gem5::Process::asyncResetCount
int asyncResetCount
Definition: process.hh:187
sc_join.hh
sc_gem5::Scheduler::schedule
void schedule(ScEvent *event, const ::sc_core::sc_time &delay)
Definition: scheduler.hh:238
sc_gem5::Process::addReset
void addReset(Reset *)
Definition: process.cc:298
sc_gem5::Process::procKind
virtual ::sc_core::sc_curr_proc_kind procKind() const =0
sc_gem5
Definition: sc_clock.cc:42
sc_core::sc_allow_process_control_corners
bool sc_allow_process_control_corners
Definition: sc_process_handle.cc:326
event.hh
sc_gem5::Process::_timedOut
bool _timedOut
Definition: process.hh:168
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
sc_gem5::Process::_terminated
bool _terminated
Definition: process.hh:175
sc_gem5::scheduler
Scheduler scheduler
Definition: scheduler.cc:489
ArmISA::s
Bitfield< 4 > s
Definition: miscregs_types.hh:556
sc_gem5::Process::signalReset
void signalReset(bool set, bool sync)
Definition: process.cc:241
sc_gem5::Process::_isUnwinding
bool _isUnwinding
Definition: process.hh:174
sc_gem5::ProcessFuncWrapper::call
virtual void call()=0
sc_core::SC_RUNNING
@ SC_RUNNING
Definition: sc_main.hh:87
sc_gem5::Process::joinWaiters
std::vector<::sc_core::sc_join * > joinWaiters
Definition: process.hh:201
sc_gem5::Process::needsStart
bool needsStart() const
Definition: process.hh:66
sc_gem5::Process::clearDynamic
void clearDynamic()
Definition: process.hh:110
sc_gem5::Process::waitCount
void waitCount(int count)
Definition: process.hh:138
sc_gem5::Sensitivity::clear
virtual void clear()=0
sc_gem5::Process::_newest
static Process * _newest
Definition: process.hh:147
Ps2::Reset
@ Reset
Definition: types.hh:63
scheduler.hh
sc_gem5::Process::func
ProcessFuncWrapper * func
Definition: process.hh:163
ArmISA::v
Bitfield< 28 > v
Definition: miscregs_types.hh:51
sc_gem5::Process::resume
void resume(bool inc_kids)
Definition: process.cc:98
sc_gem5::Sensitivity
Definition: sensitivity.hh:62
sc_core::SC_ID_PROCESS_CONTROL_CORNER_CASE_
const char SC_ID_PROCESS_CONTROL_CORNER_CASE_[]
Definition: messages.cc:135
sc_gem5::Process::ready
void ready()
Definition: process.cc:355

Generated on Wed Sep 30 2020 14:02:00 for gem5 by doxygen 1.8.17