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