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 * Authors: Gabe Black 28 */ 29 30#include "systemc/core/process.hh" 31 32#include "base/logging.hh" 33#include "systemc/core/event.hh" 34#include "systemc/core/port.hh" 35#include "systemc/core/scheduler.hh"
| 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 * Authors: Gabe Black 28 */ 29 30#include "systemc/core/process.hh" 31 32#include "base/logging.hh" 33#include "systemc/core/event.hh" 34#include "systemc/core/port.hh" 35#include "systemc/core/scheduler.hh"
|
| 36#include "systemc/ext/core/messages.hh"
|
36#include "systemc/ext/core/sc_join.hh" 37#include "systemc/ext/core/sc_main.hh" 38#include "systemc/ext/core/sc_process_handle.hh" 39#include "systemc/ext/utils/sc_report_handler.hh" 40 41namespace sc_gem5 42{ 43 44class UnwindExceptionReset : public ::sc_core::sc_unwind_exception 45{ 46 public: 47 UnwindExceptionReset() { _isReset = true; } 48}; 49 50class UnwindExceptionKill : public ::sc_core::sc_unwind_exception 51{ 52 public: 53 UnwindExceptionKill() {} 54}; 55 56template <typename T> 57struct BuiltinExceptionWrapper : public ExceptionWrapperBase 58{ 59 public: 60 T t; 61 void throw_it() override { throw t; } 62}; 63 64BuiltinExceptionWrapper<UnwindExceptionReset> resetException; 65BuiltinExceptionWrapper<UnwindExceptionKill> killException; 66 67 68void 69Process::forEachKid(const std::function<void(Process *)> &work) 70{ 71 for (auto &kid: get_child_objects()) { 72 Process *p_kid = dynamic_cast<Process *>(kid); 73 if (p_kid) 74 work(p_kid); 75 } 76} 77 78void 79Process::suspend(bool inc_kids) 80{ 81 if (inc_kids) 82 forEachKid([](Process *p) { p->suspend(true); }); 83 84 if (!_suspended) { 85 _suspended = true; 86 _suspendedReady = scheduler.suspend(this); 87 88 if (procKind() != ::sc_core::SC_METHOD_PROC_ && 89 scheduler.current() == this) { 90 // This isn't in the spec, but Accellera says that a thread that 91 // self suspends should be marked ready immediately when it's 92 // resumed. 93 _suspendedReady = true; 94 scheduler.yield(); 95 } 96 } 97} 98 99void 100Process::resume(bool inc_kids) 101{ 102 if (inc_kids) 103 forEachKid([](Process *p) { p->resume(true); }); 104 105 if (_suspended) { 106 _suspended = false; 107 if (_suspendedReady) 108 scheduler.resume(this); 109 _suspendedReady = false; 110 } 111} 112 113void 114Process::disable(bool inc_kids) 115{ 116 if (inc_kids) 117 forEachKid([](Process *p) { p->disable(true); }); 118 119 if (!::sc_core::sc_allow_process_control_corners && 120 timeoutEvent.scheduled()) { 121 std::string message("attempt to disable a thread with timeout wait: "); 122 message += name();
| 37#include "systemc/ext/core/sc_join.hh" 38#include "systemc/ext/core/sc_main.hh" 39#include "systemc/ext/core/sc_process_handle.hh" 40#include "systemc/ext/utils/sc_report_handler.hh" 41 42namespace sc_gem5 43{ 44 45class UnwindExceptionReset : public ::sc_core::sc_unwind_exception 46{ 47 public: 48 UnwindExceptionReset() { _isReset = true; } 49}; 50 51class UnwindExceptionKill : public ::sc_core::sc_unwind_exception 52{ 53 public: 54 UnwindExceptionKill() {} 55}; 56 57template <typename T> 58struct BuiltinExceptionWrapper : public ExceptionWrapperBase 59{ 60 public: 61 T t; 62 void throw_it() override { throw t; } 63}; 64 65BuiltinExceptionWrapper<UnwindExceptionReset> resetException; 66BuiltinExceptionWrapper<UnwindExceptionKill> killException; 67 68 69void 70Process::forEachKid(const std::function<void(Process *)> &work) 71{ 72 for (auto &kid: get_child_objects()) { 73 Process *p_kid = dynamic_cast<Process *>(kid); 74 if (p_kid) 75 work(p_kid); 76 } 77} 78 79void 80Process::suspend(bool inc_kids) 81{ 82 if (inc_kids) 83 forEachKid([](Process *p) { p->suspend(true); }); 84 85 if (!_suspended) { 86 _suspended = true; 87 _suspendedReady = scheduler.suspend(this); 88 89 if (procKind() != ::sc_core::SC_METHOD_PROC_ && 90 scheduler.current() == this) { 91 // This isn't in the spec, but Accellera says that a thread that 92 // self suspends should be marked ready immediately when it's 93 // resumed. 94 _suspendedReady = true; 95 scheduler.yield(); 96 } 97 } 98} 99 100void 101Process::resume(bool inc_kids) 102{ 103 if (inc_kids) 104 forEachKid([](Process *p) { p->resume(true); }); 105 106 if (_suspended) { 107 _suspended = false; 108 if (_suspendedReady) 109 scheduler.resume(this); 110 _suspendedReady = false; 111 } 112} 113 114void 115Process::disable(bool inc_kids) 116{ 117 if (inc_kids) 118 forEachKid([](Process *p) { p->disable(true); }); 119 120 if (!::sc_core::sc_allow_process_control_corners && 121 timeoutEvent.scheduled()) { 122 std::string message("attempt to disable a thread with timeout wait: "); 123 message += name();
|
123 SC_REPORT_ERROR("Undefined process control interaction",
| 124 SC_REPORT_ERROR(sc_core::SC_ID_PROCESS_CONTROL_CORNER_CASE_,
|
124 message.c_str()); 125 } 126 127 _disabled = true; 128} 129 130void 131Process::enable(bool inc_kids) 132{ 133 134 if (inc_kids) 135 forEachKid([](Process *p) { p->enable(true); }); 136 137 _disabled = false; 138} 139 140void 141Process::kill(bool inc_kids) 142{ 143 if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) {
| 125 message.c_str()); 126 } 127 128 _disabled = true; 129} 130 131void 132Process::enable(bool inc_kids) 133{ 134 135 if (inc_kids) 136 forEachKid([](Process *p) { p->enable(true); }); 137 138 _disabled = false; 139} 140 141void 142Process::kill(bool inc_kids) 143{ 144 if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) {
|
144 SC_REPORT_ERROR( 145 "(E572) a process may not be killed before it is initialized",
| 145 SC_REPORT_ERROR(sc_core::SC_ID_KILL_PROCESS_WHILE_UNITIALIZED_,
|
146 name()); 147 } 148 149 // Propogate the kill to our children no matter what happens to us. 150 if (inc_kids) 151 forEachKid([](Process *p) { p->kill(true); }); 152 153 // If we're in the middle of unwinding, ignore the kill request. 154 if (_isUnwinding) 155 return; 156 157 // Update our state. 158 terminate(); 159 _isUnwinding = true; 160 161 // Make sure this process isn't marked ready 162 popListNode(); 163 164 // Inject the kill exception into this process if it's started. 165 if (!_needsStart) 166 injectException(killException); 167} 168 169void 170Process::reset(bool inc_kids) 171{ 172 if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) {
| 146 name()); 147 } 148 149 // Propogate the kill to our children no matter what happens to us. 150 if (inc_kids) 151 forEachKid([](Process *p) { p->kill(true); }); 152 153 // If we're in the middle of unwinding, ignore the kill request. 154 if (_isUnwinding) 155 return; 156 157 // Update our state. 158 terminate(); 159 _isUnwinding = true; 160 161 // Make sure this process isn't marked ready 162 popListNode(); 163 164 // Inject the kill exception into this process if it's started. 165 if (!_needsStart) 166 injectException(killException); 167} 168 169void 170Process::reset(bool inc_kids) 171{ 172 if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) {
|
173 SC_REPORT_ERROR( 174 "(E573) a process may not be asynchronously reset while" 175 "the simulation is not running", name());
| 173 SC_REPORT_ERROR(sc_core::SC_ID_RESET_PROCESS_WHILE_NOT_RUNNING_, 174 name());
|
176 } 177 178 // Propogate the reset to our children no matter what happens to us. 179 if (inc_kids) 180 forEachKid([](Process *p) { p->reset(true); }); 181 182 // If we're in the middle of unwinding, ignore the reset request. 183 if (_isUnwinding) 184 return; 185 186 // Clear suspended ready since we're about to run regardless. 187 _suspendedReady = false; 188 189 _resetEvent.notify(); 190 191 if (_needsStart) { 192 scheduler.runNow(this); 193 } else { 194 _isUnwinding = true; 195 injectException(resetException); 196 } 197} 198 199void 200Process::throw_it(ExceptionWrapperBase &exc, bool inc_kids) 201{
| 175 } 176 177 // Propogate the reset to our children no matter what happens to us. 178 if (inc_kids) 179 forEachKid([](Process *p) { p->reset(true); }); 180 181 // If we're in the middle of unwinding, ignore the reset request. 182 if (_isUnwinding) 183 return; 184 185 // Clear suspended ready since we're about to run regardless. 186 _suspendedReady = false; 187 188 _resetEvent.notify(); 189 190 if (_needsStart) { 191 scheduler.runNow(this); 192 } else { 193 _isUnwinding = true; 194 injectException(resetException); 195 } 196} 197 198void 199Process::throw_it(ExceptionWrapperBase &exc, bool inc_kids) 200{
|
202 if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) { 203 SC_REPORT_ERROR( 204 "(E574) throw_it not allowed unless simulation is running ", 205 name()); 206 }
| 201 if (::sc_core::sc_get_status() != ::sc_core::SC_RUNNING) 202 SC_REPORT_ERROR(sc_core::SC_ID_THROW_IT_WHILE_NOT_RUNNING_, name());
|
207 208 if (inc_kids) 209 forEachKid([&exc](Process *p) { p->throw_it(exc, true); }); 210 211 if (_needsStart || _terminated || 212 procKind() == ::sc_core::SC_METHOD_PROC_) {
| 203 204 if (inc_kids) 205 forEachKid([&exc](Process *p) { p->throw_it(exc, true); }); 206 207 if (_needsStart || _terminated || 208 procKind() == ::sc_core::SC_METHOD_PROC_) {
|
213 SC_REPORT_WARNING("(W556) throw_it on method/non-running process " 214 "is being ignored ", name());
| 209 SC_REPORT_WARNING(sc_core::SC_ID_THROW_IT_IGNORED_, name());
|
215 return; 216 } 217 218 injectException(exc); 219} 220 221void 222Process::injectException(ExceptionWrapperBase &exc) 223{ 224 excWrapper = &exc; 225 scheduler.runNow(this); 226}; 227 228void 229Process::syncResetOn(bool inc_kids) 230{ 231 if (inc_kids) 232 forEachKid([](Process *p) { p->syncResetOn(true); }); 233 234 _syncReset = true; 235} 236 237void 238Process::syncResetOff(bool inc_kids) 239{ 240 if (inc_kids) 241 forEachKid([](Process *p) { p->syncResetOff(true); }); 242 243 _syncReset = false; 244} 245 246void 247Process::signalReset(bool set, bool sync) 248{ 249 if (set) { 250 waitCount(0); 251 if (sync) { 252 syncResetCount++; 253 } else { 254 asyncResetCount++; 255 cancelTimeout(); 256 clearDynamic(); 257 scheduler.runNext(this); 258 } 259 } else { 260 if (sync) 261 syncResetCount--; 262 else 263 asyncResetCount--; 264 } 265} 266 267void 268Process::run() 269{ 270 bool reset; 271 do { 272 reset = false; 273 try { 274 func->call(); 275 } catch(ScHalt) { 276 std::cout << "Terminating process " << name() << std::endl; 277 } catch(const ::sc_core::sc_unwind_exception &exc) { 278 reset = exc.is_reset(); 279 _isUnwinding = false; 280 } catch (...) { 281 throw; 282 } 283 } while (reset); 284 needsStart(true); 285} 286 287void 288Process::addStatic(StaticSensitivity *s) 289{ 290 staticSensitivities.push_back(s); 291} 292 293void 294Process::setDynamic(DynamicSensitivity *s) 295{ 296 if (dynamicSensitivity) { 297 dynamicSensitivity->clear(); 298 delete dynamicSensitivity; 299 } 300 dynamicSensitivity = s; 301} 302 303void 304Process::addReset(Reset *reset) 305{ 306 resets.push_back(reset); 307} 308 309void 310Process::cancelTimeout() 311{ 312 if (timeoutEvent.scheduled()) 313 scheduler.deschedule(&timeoutEvent); 314} 315 316void 317Process::setTimeout(::sc_core::sc_time t) 318{ 319 cancelTimeout(); 320 scheduler.schedule(&timeoutEvent, t); 321} 322 323void 324Process::timeout() 325{ 326 // A process is considered timed_out only if it was also waiting for an 327 // event but got a timeout instead. 328 _timedOut = (dynamicSensitivity != nullptr); 329 330 setDynamic(nullptr); 331 if (disabled()) 332 return; 333 334 ready(); 335} 336 337void 338Process::satisfySensitivity(Sensitivity *s) 339{ 340 if (_waitCount) { 341 _waitCount--; 342 return; 343 } 344 345 // If there's a dynamic sensitivity and this wasn't it, ignore. 346 if ((dynamicSensitivity || timeoutEvent.scheduled()) && 347 dynamicSensitivity != s) { 348 return; 349 } 350 351 _timedOut = false; 352 // This sensitivity should already be cleared by this point, or the event 353 // which triggered it will take care of it. 354 delete dynamicSensitivity; 355 dynamicSensitivity = nullptr; 356 cancelTimeout(); 357 ready(); 358} 359 360void 361Process::ready() 362{ 363 if (disabled()) 364 return; 365 if (suspended()) 366 _suspendedReady = true; 367 else 368 scheduler.ready(this); 369} 370 371void 372Process::lastReport(::sc_core::sc_report *report) 373{ 374 if (report) { 375 _lastReport = std::unique_ptr<::sc_core::sc_report>( 376 new ::sc_core::sc_report(*report)); 377 } else { 378 _lastReport = nullptr; 379 } 380} 381 382::sc_core::sc_report *Process::lastReport() const { return _lastReport.get(); } 383 384Process::Process(const char *name, ProcessFuncWrapper *func, bool internal) : 385 ::sc_core::sc_process_b(name), excWrapper(nullptr), 386 timeoutEvent([this]() { this->timeout(); }), 387 func(func), _internal(internal), _timedOut(false), _dontInitialize(false), 388 _needsStart(true), _isUnwinding(false), _terminated(false), 389 _suspended(false), _disabled(false), _syncReset(false), syncResetCount(0), 390 asyncResetCount(0), _waitCount(0), refCount(0), 391 stackSize(::Fiber::DefaultStackSize), dynamicSensitivity(nullptr) 392{ 393 _dynamic = 394 (::sc_core::sc_get_status() > 395 ::sc_core::SC_BEFORE_END_OF_ELABORATION); 396 _newest = this; 397} 398 399void 400Process::terminate() 401{ 402 _terminated = true; 403 _suspendedReady = false; 404 _suspended = false; 405 _syncReset = false; 406 clearDynamic(); 407 cancelTimeout(); 408 for (auto s: staticSensitivities) { 409 s->clear(); 410 delete s; 411 } 412 staticSensitivities.clear(); 413 414 _terminatedEvent.notify(); 415 416 for (auto jw: joinWaiters) 417 jw->signal(); 418 joinWaiters.clear(); 419} 420 421Process *Process::_newest; 422 423void 424throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids) 425{ 426 p->throw_it(exc, inc_kids); 427} 428 429void 430newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v) 431{ 432 Port *port = Port::fromPort(pb); 433 port->addReset(new Reset(p, s, v)); 434} 435 436void 437newReset(const sc_core::sc_signal_in_if<bool> *sig, Process *p, bool s, bool v) 438{ 439 Reset *reset = new Reset(p, s, v); 440 if (!reset->install(sig)) 441 delete reset; 442} 443 444} // namespace sc_gem5
| 210 return; 211 } 212 213 injectException(exc); 214} 215 216void 217Process::injectException(ExceptionWrapperBase &exc) 218{ 219 excWrapper = &exc; 220 scheduler.runNow(this); 221}; 222 223void 224Process::syncResetOn(bool inc_kids) 225{ 226 if (inc_kids) 227 forEachKid([](Process *p) { p->syncResetOn(true); }); 228 229 _syncReset = true; 230} 231 232void 233Process::syncResetOff(bool inc_kids) 234{ 235 if (inc_kids) 236 forEachKid([](Process *p) { p->syncResetOff(true); }); 237 238 _syncReset = false; 239} 240 241void 242Process::signalReset(bool set, bool sync) 243{ 244 if (set) { 245 waitCount(0); 246 if (sync) { 247 syncResetCount++; 248 } else { 249 asyncResetCount++; 250 cancelTimeout(); 251 clearDynamic(); 252 scheduler.runNext(this); 253 } 254 } else { 255 if (sync) 256 syncResetCount--; 257 else 258 asyncResetCount--; 259 } 260} 261 262void 263Process::run() 264{ 265 bool reset; 266 do { 267 reset = false; 268 try { 269 func->call(); 270 } catch(ScHalt) { 271 std::cout << "Terminating process " << name() << std::endl; 272 } catch(const ::sc_core::sc_unwind_exception &exc) { 273 reset = exc.is_reset(); 274 _isUnwinding = false; 275 } catch (...) { 276 throw; 277 } 278 } while (reset); 279 needsStart(true); 280} 281 282void 283Process::addStatic(StaticSensitivity *s) 284{ 285 staticSensitivities.push_back(s); 286} 287 288void 289Process::setDynamic(DynamicSensitivity *s) 290{ 291 if (dynamicSensitivity) { 292 dynamicSensitivity->clear(); 293 delete dynamicSensitivity; 294 } 295 dynamicSensitivity = s; 296} 297 298void 299Process::addReset(Reset *reset) 300{ 301 resets.push_back(reset); 302} 303 304void 305Process::cancelTimeout() 306{ 307 if (timeoutEvent.scheduled()) 308 scheduler.deschedule(&timeoutEvent); 309} 310 311void 312Process::setTimeout(::sc_core::sc_time t) 313{ 314 cancelTimeout(); 315 scheduler.schedule(&timeoutEvent, t); 316} 317 318void 319Process::timeout() 320{ 321 // A process is considered timed_out only if it was also waiting for an 322 // event but got a timeout instead. 323 _timedOut = (dynamicSensitivity != nullptr); 324 325 setDynamic(nullptr); 326 if (disabled()) 327 return; 328 329 ready(); 330} 331 332void 333Process::satisfySensitivity(Sensitivity *s) 334{ 335 if (_waitCount) { 336 _waitCount--; 337 return; 338 } 339 340 // If there's a dynamic sensitivity and this wasn't it, ignore. 341 if ((dynamicSensitivity || timeoutEvent.scheduled()) && 342 dynamicSensitivity != s) { 343 return; 344 } 345 346 _timedOut = false; 347 // This sensitivity should already be cleared by this point, or the event 348 // which triggered it will take care of it. 349 delete dynamicSensitivity; 350 dynamicSensitivity = nullptr; 351 cancelTimeout(); 352 ready(); 353} 354 355void 356Process::ready() 357{ 358 if (disabled()) 359 return; 360 if (suspended()) 361 _suspendedReady = true; 362 else 363 scheduler.ready(this); 364} 365 366void 367Process::lastReport(::sc_core::sc_report *report) 368{ 369 if (report) { 370 _lastReport = std::unique_ptr<::sc_core::sc_report>( 371 new ::sc_core::sc_report(*report)); 372 } else { 373 _lastReport = nullptr; 374 } 375} 376 377::sc_core::sc_report *Process::lastReport() const { return _lastReport.get(); } 378 379Process::Process(const char *name, ProcessFuncWrapper *func, bool internal) : 380 ::sc_core::sc_process_b(name), excWrapper(nullptr), 381 timeoutEvent([this]() { this->timeout(); }), 382 func(func), _internal(internal), _timedOut(false), _dontInitialize(false), 383 _needsStart(true), _isUnwinding(false), _terminated(false), 384 _suspended(false), _disabled(false), _syncReset(false), syncResetCount(0), 385 asyncResetCount(0), _waitCount(0), refCount(0), 386 stackSize(::Fiber::DefaultStackSize), dynamicSensitivity(nullptr) 387{ 388 _dynamic = 389 (::sc_core::sc_get_status() > 390 ::sc_core::SC_BEFORE_END_OF_ELABORATION); 391 _newest = this; 392} 393 394void 395Process::terminate() 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 409 _terminatedEvent.notify(); 410 411 for (auto jw: joinWaiters) 412 jw->signal(); 413 joinWaiters.clear(); 414} 415 416Process *Process::_newest; 417 418void 419throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids) 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
|