process.hh revision 13175
11761SN/A/* 22SN/A * Copyright 2018 Google, Inc. 32SN/A * 42SN/A * Redistribution and use in source and binary forms, with or without 52SN/A * modification, are permitted provided that the following conditions are 62SN/A * met: redistributions of source code must retain the above copyright 72SN/A * notice, this list of conditions and the following disclaimer; 82SN/A * redistributions in binary form must reproduce the above copyright 92SN/A * notice, this list of conditions and the following disclaimer in the 102SN/A * documentation and/or other materials provided with the distribution; 112SN/A * neither the name of the copyright holders nor the names of its 122SN/A * contributors may be used to endorse or promote products derived from 132SN/A * this software without specific prior written permission. 142SN/A * 152SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262665Ssaidi@eecs.umich.edu * 272665Ssaidi@eecs.umich.edu * Authors: Gabe Black 282SN/A */ 292SN/A 302SN/A#ifndef __SYSTEMC_CORE_PROCESS_HH__ 312SN/A#define __SYSTEMC_CORE_PROCESS_HH__ 322SN/A 33705SN/A#include <functional> 342SN/A#include <memory> 352SN/A#include <vector> 362SN/A 376661Snate@binkert.org#include "base/fiber.hh" 382SN/A#include "sim/eventq.hh" 396984Snate@binkert.org#include "systemc/core/bindinfo.hh" 406984Snate@binkert.org#include "systemc/core/event.hh" 412SN/A#include "systemc/core/list.hh" 426984Snate@binkert.org#include "systemc/core/object.hh" 436984Snate@binkert.org#include "systemc/core/sched_event.hh" 446984Snate@binkert.org#include "systemc/ext/core/sc_event.hh" 456984Snate@binkert.org#include "systemc/ext/core/sc_export.hh" 466984Snate@binkert.org#include "systemc/ext/core/sc_interface.hh" 476984Snate@binkert.org#include "systemc/ext/core/sc_module.hh" 486984Snate@binkert.org#include "systemc/ext/core/sc_port.hh" 496661Snate@binkert.org#include "systemc/ext/core/sc_process_handle.hh" 506984Snate@binkert.org#include "systemc/ext/utils/sc_report.hh" 516984Snate@binkert.org 526984Snate@binkert.orgnamespace sc_gem5 536984Snate@binkert.org{ 546984Snate@binkert.org 556984Snate@binkert.orgclass ScHalt 566984Snate@binkert.org{}; 576984Snate@binkert.org 586984Snate@binkert.orgclass Sensitivity 596984Snate@binkert.org{ 606984Snate@binkert.org protected: 616984Snate@binkert.org Process *process; 626984Snate@binkert.org 636984Snate@binkert.org public: 646984Snate@binkert.org Sensitivity(Process *p) : process(p) {} 656984Snate@binkert.org virtual ~Sensitivity() {} 666661Snate@binkert.org 676984Snate@binkert.org virtual void notifyWork(Event *e); 686984Snate@binkert.org void notify(Event *e); 696984Snate@binkert.org void notify() { notify(nullptr); } 706984Snate@binkert.org 716984Snate@binkert.org const std::string name(); 726984Snate@binkert.org}; 736661Snate@binkert.org 746984Snate@binkert.orgclass SensitivityTimeout : virtual public Sensitivity 756984Snate@binkert.org{ 766984Snate@binkert.org private: 776984Snate@binkert.org void timeout(); 786984Snate@binkert.org ScEvent timeoutEvent; 796984Snate@binkert.org 806984Snate@binkert.org public: 816984Snate@binkert.org SensitivityTimeout(Process *p, ::sc_core::sc_time t); 826984Snate@binkert.org ~SensitivityTimeout(); 836984Snate@binkert.org}; 846984Snate@binkert.org 856984Snate@binkert.orgclass SensitivityEvent : virtual public Sensitivity 866984Snate@binkert.org{ 876984Snate@binkert.org private: 886984Snate@binkert.org const ::sc_core::sc_event *event; 896984Snate@binkert.org 906984Snate@binkert.org public: 916661Snate@binkert.org SensitivityEvent(Process *p, const ::sc_core::sc_event *e); 926984Snate@binkert.org ~SensitivityEvent(); 936984Snate@binkert.org}; 946984Snate@binkert.org 956984Snate@binkert.org//XXX This sensitivity can't be reused. To reset it, it has to be deleted and 966984Snate@binkert.org//recreated. That works for dynamic sensitivities, but not for static. 976661Snate@binkert.org//Fortunately processes can't be statically sensitive to sc_event_and_lists. 986984Snate@binkert.orgclass SensitivityEventAndList : virtual public Sensitivity 996661Snate@binkert.org{ 1006984Snate@binkert.org private: 1016984Snate@binkert.org const ::sc_core::sc_event_and_list *list; 1026984Snate@binkert.org int count; 1036661Snate@binkert.org 1046984Snate@binkert.org public: 1056984Snate@binkert.org SensitivityEventAndList( 1066661Snate@binkert.org Process *p, const ::sc_core::sc_event_and_list *list); 1076984Snate@binkert.org ~SensitivityEventAndList(); 1086984Snate@binkert.org 1096984Snate@binkert.org void notifyWork(Event *e) override; 1106984Snate@binkert.org}; 1116984Snate@binkert.org 1126661Snate@binkert.orgclass SensitivityEventOrList : virtual public Sensitivity 1136984Snate@binkert.org{ 1146984Snate@binkert.org private: 1156984Snate@binkert.org const ::sc_core::sc_event_or_list *list; 1166984Snate@binkert.org 1172SN/A public: 1186984Snate@binkert.org SensitivityEventOrList( 1196984Snate@binkert.org Process *p, const ::sc_core::sc_event_or_list *list); 1206984Snate@binkert.org ~SensitivityEventOrList(); 1216984Snate@binkert.org}; 1226984Snate@binkert.org 1236984Snate@binkert.org// Combined sensitivities. These trigger when any of their parts do. 1242SN/A 1256984Snate@binkert.orgclass SensitivityTimeoutAndEvent : 1266984Snate@binkert.org public SensitivityTimeout, public SensitivityEvent 1276984Snate@binkert.org{ 1286984Snate@binkert.org public: 1296984Snate@binkert.org SensitivityTimeoutAndEvent( 1302SN/A Process *p, ::sc_core::sc_time t, const ::sc_core::sc_event *e) : 1316984Snate@binkert.org Sensitivity(p), SensitivityTimeout(p, t), SensitivityEvent(p, e) 1326984Snate@binkert.org {} 1332SN/A}; 1346984Snate@binkert.org 1356984Snate@binkert.orgclass SensitivityTimeoutAndEventAndList : 1366984Snate@binkert.org public SensitivityTimeout, public SensitivityEventAndList 1376984Snate@binkert.org{ 1386984Snate@binkert.org public: 1396984Snate@binkert.org SensitivityTimeoutAndEventAndList( 1406984Snate@binkert.org Process *p, ::sc_core::sc_time t, 1416984Snate@binkert.org const ::sc_core::sc_event_and_list *eal) : 1426984Snate@binkert.org Sensitivity(p), SensitivityTimeout(p, t), 1436984Snate@binkert.org SensitivityEventAndList(p, eal) 1446984Snate@binkert.org {} 1456984Snate@binkert.org 1466984Snate@binkert.org void notifyWork(Event *e) override; 1476984Snate@binkert.org}; 1486984Snate@binkert.org 1496984Snate@binkert.orgclass SensitivityTimeoutAndEventOrList : 1506984Snate@binkert.org public SensitivityTimeout, public SensitivityEventOrList 1516984Snate@binkert.org{ 1526984Snate@binkert.org public: 1536984Snate@binkert.org SensitivityTimeoutAndEventOrList( 1546984Snate@binkert.org Process *p, ::sc_core::sc_time t, 1556984Snate@binkert.org const ::sc_core::sc_event_or_list *eol) : 1566984Snate@binkert.org Sensitivity(p), SensitivityTimeout(p, t), 1576984Snate@binkert.org SensitivityEventOrList(p, eol) 1586984Snate@binkert.org {} 1596984Snate@binkert.org}; 1606984Snate@binkert.org 1616984Snate@binkert.orgtypedef std::vector<Sensitivity *> Sensitivities; 1626984Snate@binkert.org 1636984Snate@binkert.org 1646984Snate@binkert.org/* 1656984Snate@binkert.org * Pending sensitivities. These are records of sensitivities to install later, 1666984Snate@binkert.org * once all the information to configure them is available. 1676984Snate@binkert.org */ 1686984Snate@binkert.org 1696984Snate@binkert.orgclass PendingSensitivity 1706984Snate@binkert.org{ 1716984Snate@binkert.org protected: 1726984Snate@binkert.org Process *process; 1736984Snate@binkert.org 1746984Snate@binkert.org public: 1756984Snate@binkert.org virtual void finalize(Sensitivities &s) = 0; 1766984Snate@binkert.org PendingSensitivity(Process *p) : process(p) {} 1776984Snate@binkert.org virtual ~PendingSensitivity() {} 1786984Snate@binkert.org}; 1796984Snate@binkert.org 1806984Snate@binkert.orgclass PendingSensitivityEvent : public PendingSensitivity 1816984Snate@binkert.org{ 1826984Snate@binkert.org private: 1836984Snate@binkert.org const sc_core::sc_event *event; 1846984Snate@binkert.org 1856984Snate@binkert.org public: 1866984Snate@binkert.org PendingSensitivityEvent(Process *p, const sc_core::sc_event *e) : 1876984Snate@binkert.org PendingSensitivity(p), event(e) {} 1886984Snate@binkert.org 1896984Snate@binkert.org void 1906984Snate@binkert.org finalize(Sensitivities &s) override 1916984Snate@binkert.org { 1926984Snate@binkert.org s.push_back(new SensitivityEvent(process, event)); 1936984Snate@binkert.org } 1946984Snate@binkert.org}; 1956984Snate@binkert.org 1966984Snate@binkert.orgclass PendingSensitivityInterface : public PendingSensitivity 1976984Snate@binkert.org{ 1986984Snate@binkert.org private: 1996984Snate@binkert.org const sc_core::sc_interface *interface; 2006984Snate@binkert.org 2016984Snate@binkert.org public: 2026984Snate@binkert.org PendingSensitivityInterface(Process *p, const sc_core::sc_interface *i) : 2036984Snate@binkert.org PendingSensitivity(p), interface(i) 2046984Snate@binkert.org {} 2056984Snate@binkert.org 2066984Snate@binkert.org void 2076984Snate@binkert.org finalize(Sensitivities &s) override 2086984Snate@binkert.org { 2096984Snate@binkert.org s.push_back(new SensitivityEvent(process, 2106984Snate@binkert.org &interface->default_event())); 2116984Snate@binkert.org } 2126984Snate@binkert.org}; 2136984Snate@binkert.org 2146984Snate@binkert.orgclass PendingSensitivityPort : public PendingSensitivity 2156984Snate@binkert.org{ 2166984Snate@binkert.org private: 2176984Snate@binkert.org const sc_core::sc_port_base *port; 2186984Snate@binkert.org 2196984Snate@binkert.org public: 2206984Snate@binkert.org PendingSensitivityPort(Process *p, const sc_core::sc_port_base *pb) : 2216984Snate@binkert.org PendingSensitivity(p), port(pb) 2226984Snate@binkert.org {} 2236984Snate@binkert.org 2246661Snate@binkert.org void 2256984Snate@binkert.org finalize(Sensitivities &s) override 2266984Snate@binkert.org { 2276984Snate@binkert.org for (int i = 0; i < port->size(); i++) { 2286984Snate@binkert.org const ::sc_core::sc_event *e = 2296984Snate@binkert.org &port->_gem5Interface(i)->default_event(); 2306984Snate@binkert.org s.push_back(new SensitivityEvent(process, e)); 2316984Snate@binkert.org } 2326984Snate@binkert.org } 2332SN/A}; 2346984Snate@binkert.org 2356984Snate@binkert.orgclass PendingSensitivityExport : public PendingSensitivity 2366984Snate@binkert.org{ 2376984Snate@binkert.org private: 2386984Snate@binkert.org const sc_core::sc_export_base *exp; 2392SN/A 2406984Snate@binkert.org public: 2416984Snate@binkert.org PendingSensitivityExport(Process *p, const sc_core::sc_export_base *exp) : 2426984Snate@binkert.org PendingSensitivity(p), exp(exp) 2432023SN/A {} 2446984Snate@binkert.org 2456984Snate@binkert.org void 2462023SN/A finalize(Sensitivities &s) override 2476984Snate@binkert.org { 2486984Snate@binkert.org s.push_back(new SensitivityEvent(process, 2496984Snate@binkert.org &exp->get_interface()->default_event())); 2506984Snate@binkert.org } 2516984Snate@binkert.org}; 2526984Snate@binkert.org 2536984Snate@binkert.orgclass PendingSensitivityFinder : public PendingSensitivity 254715SN/A{ 255715SN/A private: 256715SN/A const sc_core::sc_event_finder *finder; 257715SN/A 258715SN/A public: 259715SN/A PendingSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) : 260715SN/A PendingSensitivity(p), finder(f) 261715SN/A {} 262715SN/A 263715SN/A void 264715SN/A finalize(Sensitivities &s) override 265715SN/A { 266715SN/A const ::sc_core::sc_port_base *port = finder->port(); 267715SN/A int size = port->size(); 268715SN/A for (int i = 0; i < size; i++) { 2692155SN/A ::sc_core::sc_interface *interface = port->_gem5Interface(i); 270715SN/A const ::sc_core::sc_event *event = &finder->find_event(interface); 271715SN/A s.push_back(new SensitivityEvent(process, event)); 272715SN/A } 273715SN/A } 274715SN/A}; 275715SN/A 276715SN/Atypedef std::vector<PendingSensitivity *> PendingSensitivities; 277715SN/A 278715SN/A 279715SN/Aclass Process : public ::sc_core::sc_process_b, public ListNode 280715SN/A{ 281715SN/A public: 282715SN/A virtual ::sc_core::sc_curr_proc_kind procKind() const = 0; 283715SN/A bool needsStart() const { return _needsStart; } 284715SN/A void needsStart(bool ns) { _needsStart = ns; } 285715SN/A bool dynamic() const { return _dynamic; } 286715SN/A bool isUnwinding() const { return _isUnwinding; } 287715SN/A void isUnwinding(bool v) { _isUnwinding = v; } 288715SN/A bool terminated() const { return _terminated; } 289715SN/A 2906661Snate@binkert.org void forEachKid(const std::function<void(Process *)> &work); 2916661Snate@binkert.org 2926661Snate@binkert.org bool suspended() const { return _suspended; } 2936661Snate@binkert.org bool disabled() const { return _disabled; } 2946661Snate@binkert.org 295715SN/A void suspend(bool inc_kids); 296715SN/A void resume(bool inc_kids); 297715SN/A void disable(bool inc_kids); 298715SN/A void enable(bool inc_kids); 299715SN/A 300715SN/A void kill(bool inc_kids); 301715SN/A void reset(bool inc_kids); 302715SN/A virtual void throw_it(ExceptionWrapperBase &exc, bool inc_kids); 303715SN/A 304715SN/A void injectException(ExceptionWrapperBase &exc); 305715SN/A ExceptionWrapperBase *excWrapper; 306715SN/A 307715SN/A void syncResetOn(bool inc_kids); 308715SN/A void syncResetOff(bool inc_kids); 3096983Snate@binkert.org 310715SN/A void incref() { refCount++; } 311715SN/A void decref() { refCount--; } 312715SN/A 313715SN/A const ::sc_core::sc_event &resetEvent() { return _resetEvent; } 314715SN/A const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; } 315715SN/A 316715SN/A // This should only be called before initialization. 317715SN/A void dontInitialize(); 318715SN/A 319715SN/A void setStackSize(size_t size) { stackSize = size; } 320715SN/A 321715SN/A void finalize(); 322715SN/A 323715SN/A void run(); 324715SN/A 325715SN/A void addStatic(PendingSensitivity *); 326715SN/A void setDynamic(Sensitivity *); 327715SN/A 328715SN/A void satisfySensitivity(Sensitivity *); 329715SN/A 330715SN/A void ready(); 331715SN/A 332715SN/A virtual Fiber *fiber() { return Fiber::primaryFiber(); } 3332155SN/A 334715SN/A static Process *newest() { return _newest; } 335715SN/A 336715SN/A void lastReport(::sc_core::sc_report *report); 337715SN/A ::sc_core::sc_report *lastReport() const; 338715SN/A 339715SN/A protected: 340715SN/A Process(const char *name, ProcessFuncWrapper *func); 341715SN/A 342715SN/A static Process *_newest; 343715SN/A 344715SN/A virtual ~Process() 345715SN/A { 346715SN/A popListNode(); 3472155SN/A delete func; 348715SN/A for (auto s: staticSensitivities) 349715SN/A delete s; 350715SN/A } 351715SN/A 352715SN/A ::sc_core::sc_event _resetEvent; 353715SN/A ::sc_core::sc_event _terminatedEvent; 354715SN/A 3552SN/A ProcessFuncWrapper *func; 3562SN/A sc_core::sc_curr_proc_kind _procKind; 3572SN/A bool _needsStart; 3582SN/A bool _dynamic; 3592SN/A bool _isUnwinding; 3602SN/A bool _terminated; 3612SN/A 3622SN/A void terminate(); 3632SN/A 3642SN/A bool _suspended; 3652SN/A bool _suspendedReady; 3662SN/A bool _disabled; 3672SN/A 3682SN/A bool _syncReset; 3692SN/A 3702SN/A int refCount; 3712SN/A 3722SN/A size_t stackSize; 3732SN/A 3742SN/A Sensitivities staticSensitivities; 3752SN/A PendingSensitivities pendingStaticSensitivities; 3762SN/A 3772SN/A Sensitivity *dynamicSensitivity; 3782SN/A 3792SN/A std::unique_ptr<::sc_core::sc_report> _lastReport; 3802SN/A}; 3812SN/A 3822SN/Ainline void 3832SN/ASensitivity::notifyWork(Event *e) 3842SN/A{ 3852SN/A process->satisfySensitivity(this); 3862SN/A} 3872SN/A 3882SN/Ainline void 3892SN/ASensitivity::notify(Event *e) 3902SN/A{ 3912SN/A if (!process->disabled()) 3922SN/A notifyWork(e); 3932SN/A} 3942SN/A 3952SN/Ainline const std::string 3962SN/ASensitivity::name() 3972SN/A{ 3982SN/A return std::string(process->name()) + ".timeout"; 3992SN/A} 4002SN/A 4012SN/A} // namespace sc_gem5 4022SN/A 4032SN/A#endif //__SYSTEMC_CORE_PROCESS_HH__ 4042SN/A