2 * Copyright 2018 Google, Inc.
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.
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.
30 #include "systemc/core/process.hh"
35 class UnwindExceptionReset
: public ::sc_core::sc_unwind_exception
38 const char *what() const throw() override
{ return "RESET"; }
39 bool is_reset() const override
{ return true; }
42 class UnwindExceptionKill
: public ::sc_core::sc_unwind_exception
45 const char *what() const throw() override
{ return "KILL"; }
46 bool is_reset() const override
{ return false; }
50 struct BuiltinExceptionWrapper
: public ExceptionWrapperBase
54 void throw_it() override
{ throw t
; }
57 BuiltinExceptionWrapper
<UnwindExceptionReset
> resetException
;
58 BuiltinExceptionWrapper
<UnwindExceptionKill
> killException
;
62 Process::forEachKid(const std::function
<void(Process
*)> &work
)
64 for (auto &kid
: get_child_objects()) {
65 Process
*p_kid
= dynamic_cast<Process
*>(kid
);
72 Process::suspend(bool inc_kids
)
75 forEachKid([](Process
*p
) { p
->suspend(true); });
79 //TODO Suspend this process.
82 if (procKind() != ::sc_core::SC_METHOD_PROC_
/* && we're running */) {
83 // We suspended this thread or cthread. Stop running.
88 Process::resume(bool inc_kids
)
91 forEachKid([](Process
*p
) { p
->resume(true); });
95 //TODO Resume this process.
100 Process::disable(bool inc_kids
)
103 forEachKid([](Process
*p
) { p
->disable(true); });
109 Process::enable(bool inc_kids
)
113 forEachKid([](Process
*p
) { p
->enable(true); });
119 Process::kill(bool inc_kids
)
125 // Propogate the kill to our children no matter what happens to us.
127 forEachKid([](Process
*p
) { p
->kill(true); });
129 // If we're in the middle of unwinding, ignore the kill request.
133 // Inject the kill exception into this process.
134 injectException(killException
);
136 _terminatedEvent
.notify();
140 Process::reset(bool inc_kids
)
145 // Propogate the reset to our children no matter what happens to us.
147 forEachKid([](Process
*p
) { p
->reset(true); });
149 // If we're in the middle of unwinding, ignore the reset request.
153 // Inject the reset exception into this process.
154 injectException(resetException
);
156 _resetEvent
.notify();
160 Process::throw_it(ExceptionWrapperBase
&exc
, bool inc_kids
)
163 forEachKid([&exc
](Process
*p
) { p
->throw_it(exc
, true); });
167 Process::injectException(ExceptionWrapperBase
&exc
)
170 // Let this process preempt us.
174 Process::syncResetOn(bool inc_kids
)
177 forEachKid([](Process
*p
) { p
->syncResetOn(true); });
183 Process::syncResetOff(bool inc_kids
)
186 forEachKid([](Process
*p
) { p
->syncResetOff(true); });
192 Thread::throw_it(ExceptionWrapperBase
&exc
, bool inc_kids
)
194 Process::throw_it(exc
, inc_kids
);
199 injectException(exc
);
203 throw_it_wrapper(Process
*p
, ExceptionWrapperBase
&exc
, bool inc_kids
)
205 p
->throw_it(exc
, inc_kids
);
208 } // namespace sc_gem5