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