process.hh revision 13175
1955SN/A/* 2955SN/A * Copyright 2018 Google, Inc. 31762SN/A * 4955SN/A * Redistribution and use in source and binary forms, with or without 5955SN/A * modification, are permitted provided that the following conditions are 6955SN/A * met: redistributions of source code must retain the above copyright 7955SN/A * notice, this list of conditions and the following disclaimer; 8955SN/A * redistributions in binary form must reproduce the above copyright 9955SN/A * notice, this list of conditions and the following disclaimer in the 10955SN/A * documentation and/or other materials provided with the distribution; 11955SN/A * neither the name of the copyright holders nor the names of its 12955SN/A * contributors may be used to endorse or promote products derived from 13955SN/A * this software without specific prior written permission. 14955SN/A * 15955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26955SN/A * 27955SN/A * Authors: Gabe Black 282665Ssaidi@eecs.umich.edu */ 294762Snate@binkert.org 30955SN/A#ifndef __SYSTEMC_CORE_PROCESS_HH__ 315522Snate@binkert.org#define __SYSTEMC_CORE_PROCESS_HH__ 324762Snate@binkert.org 335522Snate@binkert.org#include <functional> 34955SN/A#include <memory> 355522Snate@binkert.org#include <vector> 36955SN/A 375522Snate@binkert.org#include "base/fiber.hh" 384202Sbinkertn@umich.edu#include "sim/eventq.hh" 395742Snate@binkert.org#include "systemc/core/bindinfo.hh" 40955SN/A#include "systemc/core/event.hh" 414381Sbinkertn@umich.edu#include "systemc/core/list.hh" 424381Sbinkertn@umich.edu#include "systemc/core/object.hh" 43955SN/A#include "systemc/core/sched_event.hh" 44955SN/A#include "systemc/ext/core/sc_event.hh" 45955SN/A#include "systemc/ext/core/sc_export.hh" 464202Sbinkertn@umich.edu#include "systemc/ext/core/sc_interface.hh" 47955SN/A#include "systemc/ext/core/sc_module.hh" 484382Sbinkertn@umich.edu#include "systemc/ext/core/sc_port.hh" 494382Sbinkertn@umich.edu#include "systemc/ext/core/sc_process_handle.hh" 504382Sbinkertn@umich.edu#include "systemc/ext/utils/sc_report.hh" 515863Snate@binkert.org 525517Snate@binkert.orgnamespace sc_gem5 534762Snate@binkert.org{ 544762Snate@binkert.org 554762Snate@binkert.orgclass ScHalt 564762Snate@binkert.org{}; 574762Snate@binkert.org 584762Snate@binkert.orgclass Sensitivity 594762Snate@binkert.org{ 604762Snate@binkert.org protected: 614762Snate@binkert.org Process *process; 624762Snate@binkert.org 635522Snate@binkert.org public: 645604Snate@binkert.org Sensitivity(Process *p) : process(p) {} 655604Snate@binkert.org virtual ~Sensitivity() {} 665604Snate@binkert.org 674762Snate@binkert.org virtual void notifyWork(Event *e); 684762Snate@binkert.org void notify(Event *e); 694762Snate@binkert.org void notify() { notify(nullptr); } 705522Snate@binkert.org 715522Snate@binkert.org const std::string name(); 725522Snate@binkert.org}; 735522Snate@binkert.org 745604Snate@binkert.orgclass SensitivityTimeout : virtual public Sensitivity 755604Snate@binkert.org{ 764762Snate@binkert.org private: 774762Snate@binkert.org void timeout(); 784762Snate@binkert.org ScEvent timeoutEvent; 794762Snate@binkert.org 805522Snate@binkert.org public: 814762Snate@binkert.org SensitivityTimeout(Process *p, ::sc_core::sc_time t); 824762Snate@binkert.org ~SensitivityTimeout(); 835604Snate@binkert.org}; 845604Snate@binkert.org 855604Snate@binkert.orgclass SensitivityEvent : virtual public Sensitivity 865604Snate@binkert.org{ 875604Snate@binkert.org private: 885604Snate@binkert.org const ::sc_core::sc_event *event; 894762Snate@binkert.org 904762Snate@binkert.org public: 914762Snate@binkert.org SensitivityEvent(Process *p, const ::sc_core::sc_event *e); 924762Snate@binkert.org ~SensitivityEvent(); 935604Snate@binkert.org}; 944762Snate@binkert.org 955522Snate@binkert.org//XXX This sensitivity can't be reused. To reset it, it has to be deleted and 965522Snate@binkert.org//recreated. That works for dynamic sensitivities, but not for static. 975522Snate@binkert.org//Fortunately processes can't be statically sensitive to sc_event_and_lists. 984762Snate@binkert.orgclass SensitivityEventAndList : virtual public Sensitivity 994382Sbinkertn@umich.edu{ 1004762Snate@binkert.org private: 1014382Sbinkertn@umich.edu const ::sc_core::sc_event_and_list *list; 1025522Snate@binkert.org int count; 1034381Sbinkertn@umich.edu 1045522Snate@binkert.org public: 1054762Snate@binkert.org SensitivityEventAndList( 1064762Snate@binkert.org Process *p, const ::sc_core::sc_event_and_list *list); 1074762Snate@binkert.org ~SensitivityEventAndList(); 1085522Snate@binkert.org 1095522Snate@binkert.org void notifyWork(Event *e) override; 1105522Snate@binkert.org}; 1115522Snate@binkert.org 1125522Snate@binkert.orgclass SensitivityEventOrList : virtual public Sensitivity 1135522Snate@binkert.org{ 1145522Snate@binkert.org private: 1155522Snate@binkert.org const ::sc_core::sc_event_or_list *list; 1165522Snate@binkert.org 1174762Snate@binkert.org public: 1184762Snate@binkert.org SensitivityEventOrList( 1194762Snate@binkert.org Process *p, const ::sc_core::sc_event_or_list *list); 1204762Snate@binkert.org ~SensitivityEventOrList(); 1214762Snate@binkert.org}; 1224762Snate@binkert.org 1234762Snate@binkert.org// Combined sensitivities. These trigger when any of their parts do. 1244762Snate@binkert.org 1254762Snate@binkert.orgclass SensitivityTimeoutAndEvent : 1264762Snate@binkert.org public SensitivityTimeout, public SensitivityEvent 1274762Snate@binkert.org{ 1284762Snate@binkert.org public: 1294762Snate@binkert.org SensitivityTimeoutAndEvent( 1304762Snate@binkert.org Process *p, ::sc_core::sc_time t, const ::sc_core::sc_event *e) : 1314762Snate@binkert.org Sensitivity(p), SensitivityTimeout(p, t), SensitivityEvent(p, e) 1324762Snate@binkert.org {} 1334762Snate@binkert.org}; 1344762Snate@binkert.org 1354762Snate@binkert.orgclass SensitivityTimeoutAndEventAndList : 1364762Snate@binkert.org public SensitivityTimeout, public SensitivityEventAndList 1374762Snate@binkert.org{ 1384762Snate@binkert.org public: 1394762Snate@binkert.org SensitivityTimeoutAndEventAndList( 1404762Snate@binkert.org Process *p, ::sc_core::sc_time t, 1414762Snate@binkert.org const ::sc_core::sc_event_and_list *eal) : 1424762Snate@binkert.org Sensitivity(p), SensitivityTimeout(p, t), 1434762Snate@binkert.org SensitivityEventAndList(p, eal) 1444762Snate@binkert.org {} 1454762Snate@binkert.org 1464762Snate@binkert.org void notifyWork(Event *e) override; 1474762Snate@binkert.org}; 1484762Snate@binkert.org 1494762Snate@binkert.orgclass SensitivityTimeoutAndEventOrList : 1504762Snate@binkert.org public SensitivityTimeout, public SensitivityEventOrList 1514762Snate@binkert.org{ 152955SN/A public: 1535584Snate@binkert.org SensitivityTimeoutAndEventOrList( 1545584Snate@binkert.org Process *p, ::sc_core::sc_time t, 1555584Snate@binkert.org const ::sc_core::sc_event_or_list *eol) : 1565584Snate@binkert.org Sensitivity(p), SensitivityTimeout(p, t), 1575584Snate@binkert.org SensitivityEventOrList(p, eol) 1585584Snate@binkert.org {} 1595584Snate@binkert.org}; 1605584Snate@binkert.org 1615584Snate@binkert.orgtypedef std::vector<Sensitivity *> Sensitivities; 1625584Snate@binkert.org 1635584Snate@binkert.org 1645584Snate@binkert.org/* 1655584Snate@binkert.org * Pending sensitivities. These are records of sensitivities to install later, 1664382Sbinkertn@umich.edu * once all the information to configure them is available. 1674202Sbinkertn@umich.edu */ 1685522Snate@binkert.org 1694382Sbinkertn@umich.educlass PendingSensitivity 1704382Sbinkertn@umich.edu{ 1714382Sbinkertn@umich.edu protected: 1725584Snate@binkert.org Process *process; 1734382Sbinkertn@umich.edu 1744382Sbinkertn@umich.edu public: 1754382Sbinkertn@umich.edu virtual void finalize(Sensitivities &s) = 0; 1765192Ssaidi@eecs.umich.edu PendingSensitivity(Process *p) : process(p) {} 1775192Ssaidi@eecs.umich.edu virtual ~PendingSensitivity() {} 1785799Snate@binkert.org}; 1795799Snate@binkert.org 1805799Snate@binkert.orgclass PendingSensitivityEvent : public PendingSensitivity 1815192Ssaidi@eecs.umich.edu{ 1825799Snate@binkert.org private: 1835192Ssaidi@eecs.umich.edu const sc_core::sc_event *event; 1845799Snate@binkert.org 1855799Snate@binkert.org public: 1865192Ssaidi@eecs.umich.edu PendingSensitivityEvent(Process *p, const sc_core::sc_event *e) : 1875192Ssaidi@eecs.umich.edu PendingSensitivity(p), event(e) {} 1885192Ssaidi@eecs.umich.edu 1895192Ssaidi@eecs.umich.edu void 1905799Snate@binkert.org finalize(Sensitivities &s) override 1915192Ssaidi@eecs.umich.edu { 1925799Snate@binkert.org s.push_back(new SensitivityEvent(process, event)); 1935192Ssaidi@eecs.umich.edu } 1945192Ssaidi@eecs.umich.edu}; 1955192Ssaidi@eecs.umich.edu 1965799Snate@binkert.orgclass PendingSensitivityInterface : public PendingSensitivity 1975192Ssaidi@eecs.umich.edu{ 1985192Ssaidi@eecs.umich.edu private: 1995192Ssaidi@eecs.umich.edu const sc_core::sc_interface *interface; 2005192Ssaidi@eecs.umich.edu 2015192Ssaidi@eecs.umich.edu public: 2025192Ssaidi@eecs.umich.edu PendingSensitivityInterface(Process *p, const sc_core::sc_interface *i) : 2034382Sbinkertn@umich.edu PendingSensitivity(p), interface(i) 2044382Sbinkertn@umich.edu {} 2054382Sbinkertn@umich.edu 2062667Sstever@eecs.umich.edu void 2072667Sstever@eecs.umich.edu finalize(Sensitivities &s) override 2082667Sstever@eecs.umich.edu { 2092667Sstever@eecs.umich.edu s.push_back(new SensitivityEvent(process, 2102667Sstever@eecs.umich.edu &interface->default_event())); 2112667Sstever@eecs.umich.edu } 2125742Snate@binkert.org}; 2135742Snate@binkert.org 2145742Snate@binkert.orgclass PendingSensitivityPort : public PendingSensitivity 2152037SN/A{ 2162037SN/A private: 2172037SN/A const sc_core::sc_port_base *port; 2185793Snate@binkert.org 2195793Snate@binkert.org public: 2205793Snate@binkert.org PendingSensitivityPort(Process *p, const sc_core::sc_port_base *pb) : 2215793Snate@binkert.org PendingSensitivity(p), port(pb) 2225793Snate@binkert.org {} 2234382Sbinkertn@umich.edu 2244762Snate@binkert.org void 2255344Sstever@gmail.com finalize(Sensitivities &s) override 2264382Sbinkertn@umich.edu { 2275341Sstever@gmail.com for (int i = 0; i < port->size(); i++) { 2285742Snate@binkert.org const ::sc_core::sc_event *e = 2295742Snate@binkert.org &port->_gem5Interface(i)->default_event(); 2305742Snate@binkert.org s.push_back(new SensitivityEvent(process, e)); 2315742Snate@binkert.org } 2325742Snate@binkert.org } 2334762Snate@binkert.org}; 2345742Snate@binkert.org 2355742Snate@binkert.orgclass PendingSensitivityExport : public PendingSensitivity 2365742Snate@binkert.org{ 2375742Snate@binkert.org private: 2385742Snate@binkert.org const sc_core::sc_export_base *exp; 2395742Snate@binkert.org 2405742Snate@binkert.org public: 2415341Sstever@gmail.com PendingSensitivityExport(Process *p, const sc_core::sc_export_base *exp) : 2425742Snate@binkert.org PendingSensitivity(p), exp(exp) 2435341Sstever@gmail.com {} 2444773Snate@binkert.org 2455863Snate@binkert.org void 2461858SN/A finalize(Sensitivities &s) override 2471085SN/A { 2484382Sbinkertn@umich.edu s.push_back(new SensitivityEvent(process, 2494382Sbinkertn@umich.edu &exp->get_interface()->default_event())); 2504762Snate@binkert.org } 2514762Snate@binkert.org}; 2524762Snate@binkert.org 2535517Snate@binkert.orgclass PendingSensitivityFinder : public PendingSensitivity 2545517Snate@binkert.org{ 2555517Snate@binkert.org private: 2565517Snate@binkert.org const sc_core::sc_event_finder *finder; 2575517Snate@binkert.org 2585517Snate@binkert.org public: 2595517Snate@binkert.org PendingSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) : 2605517Snate@binkert.org PendingSensitivity(p), finder(f) 2615517Snate@binkert.org {} 2625517Snate@binkert.org 2635517Snate@binkert.org void 2645517Snate@binkert.org finalize(Sensitivities &s) override 2655517Snate@binkert.org { 2665517Snate@binkert.org const ::sc_core::sc_port_base *port = finder->port(); 2675517Snate@binkert.org int size = port->size(); 2685517Snate@binkert.org for (int i = 0; i < size; i++) { 2695517Snate@binkert.org ::sc_core::sc_interface *interface = port->_gem5Interface(i); 2705798Snate@binkert.org const ::sc_core::sc_event *event = &finder->find_event(interface); 2715517Snate@binkert.org s.push_back(new SensitivityEvent(process, event)); 2725517Snate@binkert.org } 2735517Snate@binkert.org } 2745517Snate@binkert.org}; 2755517Snate@binkert.org 2765517Snate@binkert.orgtypedef std::vector<PendingSensitivity *> PendingSensitivities; 2775517Snate@binkert.org 2785517Snate@binkert.org 2795517Snate@binkert.orgclass Process : public ::sc_core::sc_process_b, public ListNode 2805517Snate@binkert.org{ 2815517Snate@binkert.org public: 2825517Snate@binkert.org virtual ::sc_core::sc_curr_proc_kind procKind() const = 0; 2835517Snate@binkert.org bool needsStart() const { return _needsStart; } 2845517Snate@binkert.org void needsStart(bool ns) { _needsStart = ns; } 2855517Snate@binkert.org bool dynamic() const { return _dynamic; } 2865517Snate@binkert.org bool isUnwinding() const { return _isUnwinding; } 2875517Snate@binkert.org void isUnwinding(bool v) { _isUnwinding = v; } 2885517Snate@binkert.org bool terminated() const { return _terminated; } 2895517Snate@binkert.org 2905517Snate@binkert.org void forEachKid(const std::function<void(Process *)> &work); 2915517Snate@binkert.org 2925517Snate@binkert.org bool suspended() const { return _suspended; } 2935517Snate@binkert.org bool disabled() const { return _disabled; } 2945798Snate@binkert.org 2955798Snate@binkert.org void suspend(bool inc_kids); 2965517Snate@binkert.org void resume(bool inc_kids); 2975517Snate@binkert.org void disable(bool inc_kids); 2985517Snate@binkert.org void enable(bool inc_kids); 2995517Snate@binkert.org 3005517Snate@binkert.org void kill(bool inc_kids); 3015517Snate@binkert.org void reset(bool inc_kids); 3025517Snate@binkert.org virtual void throw_it(ExceptionWrapperBase &exc, bool inc_kids); 3035517Snate@binkert.org 3045517Snate@binkert.org void injectException(ExceptionWrapperBase &exc); 3055517Snate@binkert.org ExceptionWrapperBase *excWrapper; 3065517Snate@binkert.org 3075517Snate@binkert.org void syncResetOn(bool inc_kids); 3085517Snate@binkert.org void syncResetOff(bool inc_kids); 3095522Snate@binkert.org 3105517Snate@binkert.org void incref() { refCount++; } 3115517Snate@binkert.org void decref() { refCount--; } 3125517Snate@binkert.org 3135517Snate@binkert.org const ::sc_core::sc_event &resetEvent() { return _resetEvent; } 3144762Snate@binkert.org const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; } 3155517Snate@binkert.org 3165517Snate@binkert.org // This should only be called before initialization. 3174762Snate@binkert.org void dontInitialize(); 3185517Snate@binkert.org 3194762Snate@binkert.org void setStackSize(size_t size) { stackSize = size; } 3205517Snate@binkert.org 3215517Snate@binkert.org void finalize(); 3225517Snate@binkert.org 3235517Snate@binkert.org void run(); 3245517Snate@binkert.org 3255517Snate@binkert.org void addStatic(PendingSensitivity *); 3265517Snate@binkert.org void setDynamic(Sensitivity *); 3275517Snate@binkert.org 3285517Snate@binkert.org void satisfySensitivity(Sensitivity *); 3295517Snate@binkert.org 3305517Snate@binkert.org void ready(); 3315517Snate@binkert.org 3325517Snate@binkert.org virtual Fiber *fiber() { return Fiber::primaryFiber(); } 3335517Snate@binkert.org 3345517Snate@binkert.org static Process *newest() { return _newest; } 3355517Snate@binkert.org 3365517Snate@binkert.org void lastReport(::sc_core::sc_report *report); 3375517Snate@binkert.org ::sc_core::sc_report *lastReport() const; 3385517Snate@binkert.org 3395517Snate@binkert.org protected: 3405517Snate@binkert.org Process(const char *name, ProcessFuncWrapper *func); 3415517Snate@binkert.org 3425517Snate@binkert.org static Process *_newest; 3434762Snate@binkert.org 3444762Snate@binkert.org virtual ~Process() 3454762Snate@binkert.org { 3464762Snate@binkert.org popListNode(); 3474762Snate@binkert.org delete func; 3484762Snate@binkert.org for (auto s: staticSensitivities) 3495517Snate@binkert.org delete s; 3504762Snate@binkert.org } 3514762Snate@binkert.org 3524762Snate@binkert.org ::sc_core::sc_event _resetEvent; 3534762Snate@binkert.org ::sc_core::sc_event _terminatedEvent; 3544382Sbinkertn@umich.edu 3554382Sbinkertn@umich.edu ProcessFuncWrapper *func; 3565517Snate@binkert.org sc_core::sc_curr_proc_kind _procKind; 3575517Snate@binkert.org bool _needsStart; 3585517Snate@binkert.org bool _dynamic; 3595517Snate@binkert.org bool _isUnwinding; 3605798Snate@binkert.org bool _terminated; 3615798Snate@binkert.org 3625824Ssaidi@eecs.umich.edu void terminate(); 3635517Snate@binkert.org 3645517Snate@binkert.org bool _suspended; 3655863Snate@binkert.org bool _suspendedReady; 3665798Snate@binkert.org bool _disabled; 3675798Snate@binkert.org 3685798Snate@binkert.org bool _syncReset; 3695798Snate@binkert.org 3705517Snate@binkert.org int refCount; 3715517Snate@binkert.org 3725517Snate@binkert.org size_t stackSize; 3735517Snate@binkert.org 3745517Snate@binkert.org Sensitivities staticSensitivities; 3755517Snate@binkert.org PendingSensitivities pendingStaticSensitivities; 3765517Snate@binkert.org 3775517Snate@binkert.org Sensitivity *dynamicSensitivity; 3785798Snate@binkert.org 3795798Snate@binkert.org std::unique_ptr<::sc_core::sc_report> _lastReport; 3805798Snate@binkert.org}; 3815798Snate@binkert.org 3825798Snate@binkert.orginline void 3835798Snate@binkert.orgSensitivity::notifyWork(Event *e) 3845517Snate@binkert.org{ 3855517Snate@binkert.org process->satisfySensitivity(this); 3865517Snate@binkert.org} 3875517Snate@binkert.org 3885517Snate@binkert.orginline void 3895517Snate@binkert.orgSensitivity::notify(Event *e) 3905517Snate@binkert.org{ 3915517Snate@binkert.org if (!process->disabled()) 3925517Snate@binkert.org notifyWork(e); 3934762Snate@binkert.org} 3944382Sbinkertn@umich.edu 3954762Snate@binkert.orginline const std::string 3965517Snate@binkert.orgSensitivity::name() 3974382Sbinkertn@umich.edu{ 3984382Sbinkertn@umich.edu return std::string(process->name()) + ".timeout"; 3994762Snate@binkert.org} 4004762Snate@binkert.org 4014762Snate@binkert.org} // namespace sc_gem5 4024762Snate@binkert.org 4034762Snate@binkert.org#endif //__SYSTEMC_CORE_PROCESS_HH__ 4045517Snate@binkert.org