process.cc revision 12952:94fca7e8120b
112854Sgabeblack@google.com/* 212854Sgabeblack@google.com * Copyright 2018 Google, Inc. 312854Sgabeblack@google.com * 412854Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512854Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612854Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712854Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812854Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912854Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012854Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112854Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212854Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312854Sgabeblack@google.com * this software without specific prior written permission. 1412854Sgabeblack@google.com * 1512854Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612854Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712854Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812854Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912854Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012854Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112854Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212854Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312854Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412854Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512854Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612854Sgabeblack@google.com * 2712854Sgabeblack@google.com * Authors: Gabe Black 2812854Sgabeblack@google.com */ 2912854Sgabeblack@google.com 3012854Sgabeblack@google.com#include "systemc/core/process.hh" 3112854Sgabeblack@google.com 3212854Sgabeblack@google.comnamespace sc_gem5 3312854Sgabeblack@google.com{ 3412854Sgabeblack@google.com 3512854Sgabeblack@google.comclass UnwindExceptionReset : public ::sc_core::sc_unwind_exception 3612854Sgabeblack@google.com{ 3712854Sgabeblack@google.com public: 3812854Sgabeblack@google.com const char *what() const throw() override { return "RESET"; } 3912854Sgabeblack@google.com bool is_reset() const override { return true; } 4012854Sgabeblack@google.com}; 4112854Sgabeblack@google.com 4212854Sgabeblack@google.comclass UnwindExceptionKill : public ::sc_core::sc_unwind_exception 4312854Sgabeblack@google.com{ 4412854Sgabeblack@google.com public: 4512854Sgabeblack@google.com const char *what() const throw() override { return "KILL"; } 4612854Sgabeblack@google.com bool is_reset() const override { return false; } 4712854Sgabeblack@google.com}; 4812854Sgabeblack@google.com 4912854Sgabeblack@google.comtemplate <typename T> 5012854Sgabeblack@google.comstruct BuiltinExceptionWrapper : public ExceptionWrapperBase 5112854Sgabeblack@google.com{ 5212854Sgabeblack@google.com public: 5312854Sgabeblack@google.com T t; 5412854Sgabeblack@google.com void throw_it() override { throw t; } 5512854Sgabeblack@google.com}; 5612854Sgabeblack@google.com 5712854Sgabeblack@google.comBuiltinExceptionWrapper<UnwindExceptionReset> resetException; 5812854Sgabeblack@google.comBuiltinExceptionWrapper<UnwindExceptionKill> killException; 5912854Sgabeblack@google.com 6012854Sgabeblack@google.com 6112854Sgabeblack@google.comvoid 6212854Sgabeblack@google.comProcess::forEachKid(const std::function<void(Process *)> &work) 6312854Sgabeblack@google.com{ 6412854Sgabeblack@google.com for (auto &kid: get_child_objects()) { 6512854Sgabeblack@google.com Process *p_kid = dynamic_cast<Process *>(kid); 6612854Sgabeblack@google.com if (p_kid) 6712854Sgabeblack@google.com work(p_kid); 6812854Sgabeblack@google.com } 6912854Sgabeblack@google.com} 7012854Sgabeblack@google.com 7112854Sgabeblack@google.comvoid 7212854Sgabeblack@google.comProcess::suspend(bool inc_kids) 7312854Sgabeblack@google.com{ 7412854Sgabeblack@google.com if (inc_kids) 7512854Sgabeblack@google.com forEachKid([](Process *p) { p->suspend(true); }); 7612854Sgabeblack@google.com 7712854Sgabeblack@google.com if (!_suspended) { 7812854Sgabeblack@google.com _suspended = true; 7912854Sgabeblack@google.com //TODO Suspend this process. 8012854Sgabeblack@google.com } 8112854Sgabeblack@google.com 8212854Sgabeblack@google.com if (procKind() != ::sc_core::SC_METHOD_PROC_ /* && we're running */) { 8312854Sgabeblack@google.com // We suspended this thread or cthread. Stop running. 8412854Sgabeblack@google.com } 8512854Sgabeblack@google.com} 8612854Sgabeblack@google.com 8712854Sgabeblack@google.comvoid 8812854Sgabeblack@google.comProcess::resume(bool inc_kids) 8912854Sgabeblack@google.com{ 9012854Sgabeblack@google.com if (inc_kids) 9112854Sgabeblack@google.com forEachKid([](Process *p) { p->resume(true); }); 9212854Sgabeblack@google.com 9312854Sgabeblack@google.com if (_suspended) { 9412854Sgabeblack@google.com _suspended = false; 9512854Sgabeblack@google.com //TODO Resume this process. 9612854Sgabeblack@google.com } 9712854Sgabeblack@google.com} 9812854Sgabeblack@google.com 9912854Sgabeblack@google.comvoid 10012854Sgabeblack@google.comProcess::disable(bool inc_kids) 10112854Sgabeblack@google.com{ 10212854Sgabeblack@google.com if (inc_kids) 10312854Sgabeblack@google.com forEachKid([](Process *p) { p->disable(true); }); 10412854Sgabeblack@google.com 10512854Sgabeblack@google.com _disabled = true; 10612854Sgabeblack@google.com} 10712854Sgabeblack@google.com 10812854Sgabeblack@google.comvoid 10912854Sgabeblack@google.comProcess::enable(bool inc_kids) 11012854Sgabeblack@google.com{ 11112854Sgabeblack@google.com 11212854Sgabeblack@google.com if (inc_kids) 11312854Sgabeblack@google.com forEachKid([](Process *p) { p->enable(true); }); 11412854Sgabeblack@google.com 11512854Sgabeblack@google.com _disabled = false; 11612854Sgabeblack@google.com} 11712854Sgabeblack@google.com 11812854Sgabeblack@google.comvoid 11912854Sgabeblack@google.comProcess::kill(bool inc_kids) 12012854Sgabeblack@google.com{ 12112854Sgabeblack@google.com // Update our state. 12212854Sgabeblack@google.com _terminated = true; 12312854Sgabeblack@google.com _isUnwinding = true; 12412854Sgabeblack@google.com 12512854Sgabeblack@google.com // Propogate the kill to our children no matter what happens to us. 12612854Sgabeblack@google.com if (inc_kids) 12712854Sgabeblack@google.com forEachKid([](Process *p) { p->kill(true); }); 12812854Sgabeblack@google.com 12912854Sgabeblack@google.com // If we're in the middle of unwinding, ignore the kill request. 13012854Sgabeblack@google.com if (_isUnwinding) 13112854Sgabeblack@google.com return; 13212854Sgabeblack@google.com 13312854Sgabeblack@google.com // Inject the kill exception into this process. 13412854Sgabeblack@google.com injectException(killException); 13512854Sgabeblack@google.com 13612854Sgabeblack@google.com _terminatedEvent.notify(); 13712854Sgabeblack@google.com} 13812854Sgabeblack@google.com 13912854Sgabeblack@google.comvoid 14012854Sgabeblack@google.comProcess::reset(bool inc_kids) 14112854Sgabeblack@google.com{ 14212854Sgabeblack@google.com // Update our state. 14312854Sgabeblack@google.com _isUnwinding = true; 14412854Sgabeblack@google.com 14512854Sgabeblack@google.com // Propogate the reset to our children no matter what happens to us. 14612854Sgabeblack@google.com if (inc_kids) 14712854Sgabeblack@google.com forEachKid([](Process *p) { p->reset(true); }); 14812854Sgabeblack@google.com 14912854Sgabeblack@google.com // If we're in the middle of unwinding, ignore the reset request. 15012854Sgabeblack@google.com if (_isUnwinding) 15112854Sgabeblack@google.com return; 15212854Sgabeblack@google.com 15312854Sgabeblack@google.com // Inject the reset exception into this process. 15412854Sgabeblack@google.com injectException(resetException); 15512854Sgabeblack@google.com 15612854Sgabeblack@google.com _resetEvent.notify(); 15712854Sgabeblack@google.com} 15812854Sgabeblack@google.com 15912854Sgabeblack@google.comvoid 16012854Sgabeblack@google.comProcess::throw_it(ExceptionWrapperBase &exc, bool inc_kids) 16112854Sgabeblack@google.com{ 16212854Sgabeblack@google.com if (inc_kids) 16312854Sgabeblack@google.com forEachKid([&exc](Process *p) { p->throw_it(exc, true); }); 16412854Sgabeblack@google.com} 16512854Sgabeblack@google.com 16612854Sgabeblack@google.comvoid 16712854Sgabeblack@google.comProcess::injectException(ExceptionWrapperBase &exc) 16812854Sgabeblack@google.com{ 16912854Sgabeblack@google.com excWrapper = &exc; 17012854Sgabeblack@google.com // Let this process preempt us. 17112854Sgabeblack@google.com}; 17212854Sgabeblack@google.com 17312854Sgabeblack@google.comvoid 17412854Sgabeblack@google.comProcess::syncResetOn(bool inc_kids) 17512854Sgabeblack@google.com{ 17612854Sgabeblack@google.com if (inc_kids) 17712854Sgabeblack@google.com forEachKid([](Process *p) { p->syncResetOn(true); }); 17812854Sgabeblack@google.com 17912854Sgabeblack@google.com _syncReset = true; 18012854Sgabeblack@google.com} 18112854Sgabeblack@google.com 18212854Sgabeblack@google.comvoid 18312854Sgabeblack@google.comProcess::syncResetOff(bool inc_kids) 18412854Sgabeblack@google.com{ 18512854Sgabeblack@google.com if (inc_kids) 18612854Sgabeblack@google.com forEachKid([](Process *p) { p->syncResetOff(true); }); 18712854Sgabeblack@google.com 18812854Sgabeblack@google.com _syncReset = false; 18912854Sgabeblack@google.com} 19012854Sgabeblack@google.com 19112854Sgabeblack@google.comvoid 19212854Sgabeblack@google.comThread::throw_it(ExceptionWrapperBase &exc, bool inc_kids) 19312854Sgabeblack@google.com{ 19412854Sgabeblack@google.com Process::throw_it(exc, inc_kids); 19512854Sgabeblack@google.com 19612854Sgabeblack@google.com if (_terminated) 19712854Sgabeblack@google.com return; 19812854Sgabeblack@google.com 19912854Sgabeblack@google.com injectException(exc); 20012854Sgabeblack@google.com} 20112854Sgabeblack@google.com 20212854Sgabeblack@google.comvoid 20312854Sgabeblack@google.comthrow_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids) 20412854Sgabeblack@google.com{ 20512854Sgabeblack@google.com p->throw_it(exc, inc_kids); 20612854Sgabeblack@google.com} 20712854Sgabeblack@google.com 20812854Sgabeblack@google.com} // namespace sc_gem5 20912854Sgabeblack@google.com