112838Sgabeblack@google.com/*
212838Sgabeblack@google.com * Copyright 2018 Google, Inc.
312838Sgabeblack@google.com *
412838Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
512838Sgabeblack@google.com * modification, are permitted provided that the following conditions are
612838Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
712838Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
812838Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
912838Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1012838Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1112838Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1212838Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1312838Sgabeblack@google.com * this software without specific prior written permission.
1412838Sgabeblack@google.com *
1512838Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1612838Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1712838Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812838Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1912838Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2012838Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2112838Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2212838Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2312838Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2412838Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2512838Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2612838Sgabeblack@google.com *
2712838Sgabeblack@google.com * Authors: Gabe Black
2812838Sgabeblack@google.com */
2912838Sgabeblack@google.com
3012838Sgabeblack@google.com#ifndef __SYSTEMC_EXT_CORE_SC_PROCESS_HANDLE_HH__
3112838Sgabeblack@google.com#define __SYSTEMC_EXT_CORE_SC_PROCESS_HANDLE_HH__
3212838Sgabeblack@google.com
3312838Sgabeblack@google.com#include <exception>
3412838Sgabeblack@google.com#include <vector>
3512838Sgabeblack@google.com
3613128Sgabeblack@google.com#include "../utils/sc_report_handler.hh"
3713317Sgabeblack@google.com#include "messages.hh"
3813128Sgabeblack@google.com#include "sc_object.hh"
3913087Sgabeblack@google.com
4012852Sgabeblack@google.comnamespace sc_gem5
4112852Sgabeblack@google.com{
4212852Sgabeblack@google.com
4312852Sgabeblack@google.comclass Process;
4412852Sgabeblack@google.com
4512952Sgabeblack@google.comstruct ProcessFuncWrapper
4612952Sgabeblack@google.com{
4712952Sgabeblack@google.com    virtual void call() = 0;
4812952Sgabeblack@google.com    virtual ~ProcessFuncWrapper() {}
4912952Sgabeblack@google.com};
5012952Sgabeblack@google.com
5112952Sgabeblack@google.comtemplate <typename T>
5212952Sgabeblack@google.comstruct ProcessMemberFuncWrapper : public ProcessFuncWrapper
5312952Sgabeblack@google.com{
5412952Sgabeblack@google.com    typedef void (T::*TFunc)();
5512952Sgabeblack@google.com    T *t;
5612952Sgabeblack@google.com    TFunc func;
5712952Sgabeblack@google.com
5812952Sgabeblack@google.com    ProcessMemberFuncWrapper(T *t, TFunc func) : t(t), func(func) {}
5912952Sgabeblack@google.com
6012952Sgabeblack@google.com    void call() override { (t->*func)(); }
6112952Sgabeblack@google.com};
6212952Sgabeblack@google.com
6312952Sgabeblack@google.comstruct ExceptionWrapperBase
6412952Sgabeblack@google.com{
6512952Sgabeblack@google.com    virtual void throw_it() = 0;
6612952Sgabeblack@google.com};
6712952Sgabeblack@google.com
6812952Sgabeblack@google.comtemplate <typename T>
6912952Sgabeblack@google.comstruct ExceptionWrapper : public ExceptionWrapperBase
7012952Sgabeblack@google.com{
7112952Sgabeblack@google.com    const T &t;
7212952Sgabeblack@google.com    ExceptionWrapper(const T &t) : t(t) {}
7312952Sgabeblack@google.com
7412952Sgabeblack@google.com    void throw_it() { throw t; }
7512952Sgabeblack@google.com};
7612952Sgabeblack@google.com
7712952Sgabeblack@google.comvoid throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids);
7812952Sgabeblack@google.com
7912852Sgabeblack@google.com} // namespace sc_gem5
8012852Sgabeblack@google.com
8112838Sgabeblack@google.comnamespace sc_core
8212838Sgabeblack@google.com{
8312838Sgabeblack@google.com
8412838Sgabeblack@google.comclass sc_event;
8512838Sgabeblack@google.com
8612838Sgabeblack@google.comenum sc_curr_proc_kind
8712838Sgabeblack@google.com{
8812838Sgabeblack@google.com    SC_NO_PROC_,
8912838Sgabeblack@google.com    SC_METHOD_PROC_,
9012838Sgabeblack@google.com    SC_THREAD_PROC_,
9112838Sgabeblack@google.com    SC_CTHREAD_PROC_
9212838Sgabeblack@google.com};
9312838Sgabeblack@google.com
9412838Sgabeblack@google.comenum sc_descendent_inclusion_info
9512838Sgabeblack@google.com{
9612838Sgabeblack@google.com    SC_NO_DESCENDANTS,
9712838Sgabeblack@google.com    SC_INCLUDE_DESCENDANTS
9812838Sgabeblack@google.com};
9912838Sgabeblack@google.com
10012838Sgabeblack@google.comclass sc_unwind_exception : public std::exception
10112838Sgabeblack@google.com{
10212838Sgabeblack@google.com  public:
10312838Sgabeblack@google.com    virtual const char *what() const throw();
10412838Sgabeblack@google.com    virtual bool is_reset() const;
10512838Sgabeblack@google.com
10612898Sgabeblack@google.com    // Nonstandard.
10712898Sgabeblack@google.com    // These should be protected, but I think this is to enable catch by
10812898Sgabeblack@google.com    // value.
10912898Sgabeblack@google.com  public:
11012898Sgabeblack@google.com    sc_unwind_exception(const sc_unwind_exception &);
11112898Sgabeblack@google.com    virtual ~sc_unwind_exception() throw();
11212898Sgabeblack@google.com
11312838Sgabeblack@google.com  protected:
11412994Sgabeblack@google.com    bool _isReset;
11512838Sgabeblack@google.com    sc_unwind_exception();
11612838Sgabeblack@google.com};
11712838Sgabeblack@google.com
11812939Sgabeblack@google.com// Deprecated
11912939Sgabeblack@google.com// An incomplete version of sc_process_b to satisfy the tests.
12013087Sgabeblack@google.comclass sc_process_b : public sc_object
12112939Sgabeblack@google.com{
12212939Sgabeblack@google.com  public:
12313087Sgabeblack@google.com    sc_process_b(const char *name) : sc_object(name), file(nullptr), lineno(0)
12413087Sgabeblack@google.com    {}
12513087Sgabeblack@google.com    sc_process_b() : sc_object(), file(nullptr), lineno(0) {}
12613087Sgabeblack@google.com
12712939Sgabeblack@google.com    const char *file;
12812939Sgabeblack@google.com    int lineno;
12912939Sgabeblack@google.com};
13012939Sgabeblack@google.com
13113087Sgabeblack@google.com// Nonstandard
13213087Sgabeblack@google.comvoid sc_set_location(const char *file, int lineno);
13313087Sgabeblack@google.com
13412939Sgabeblack@google.com// Deprecated
13512939Sgabeblack@google.comsc_process_b *sc_get_curr_process_handle();
13612939Sgabeblack@google.comstatic inline sc_process_b *
13712939Sgabeblack@google.comsc_get_current_process_b()
13812939Sgabeblack@google.com{
13912939Sgabeblack@google.com    return sc_get_curr_process_handle();
14012939Sgabeblack@google.com}
14112939Sgabeblack@google.com
14212939Sgabeblack@google.com// Deprecated/nonstandard
14312939Sgabeblack@google.comstruct sc_curr_proc_info
14412939Sgabeblack@google.com{
14512939Sgabeblack@google.com    sc_process_b *process_handle;
14612939Sgabeblack@google.com    sc_curr_proc_kind kind;
14712939Sgabeblack@google.com    sc_curr_proc_info() : process_handle(NULL), kind(SC_NO_PROC_) {}
14812939Sgabeblack@google.com};
14912939Sgabeblack@google.comtypedef const sc_curr_proc_info *sc_curr_proc_handle;
15012939Sgabeblack@google.com
15112838Sgabeblack@google.comclass sc_process_handle
15212838Sgabeblack@google.com{
15312852Sgabeblack@google.com  private:
15412852Sgabeblack@google.com    ::sc_gem5::Process *_gem5_process;
15512852Sgabeblack@google.com
15612838Sgabeblack@google.com  public:
15712838Sgabeblack@google.com    sc_process_handle();
15812838Sgabeblack@google.com    sc_process_handle(const sc_process_handle &);
15912838Sgabeblack@google.com    explicit sc_process_handle(sc_object *);
16012838Sgabeblack@google.com    ~sc_process_handle();
16112838Sgabeblack@google.com
16212852Sgabeblack@google.com    // These non-standard operators provide access to the data structure which
16312852Sgabeblack@google.com    // actually tracks the process within gem5. By making them operators, we
16412852Sgabeblack@google.com    // can minimize the symbols added to the class namespace.
16512852Sgabeblack@google.com    operator ::sc_gem5::Process * () const { return _gem5_process; }
16612852Sgabeblack@google.com    sc_process_handle &
16712852Sgabeblack@google.com    operator = (::sc_gem5::Process *p)
16812852Sgabeblack@google.com    {
16912852Sgabeblack@google.com        _gem5_process = p;
17012852Sgabeblack@google.com        return *this;
17112852Sgabeblack@google.com    }
17212852Sgabeblack@google.com
17312838Sgabeblack@google.com    bool valid() const;
17412838Sgabeblack@google.com
17512838Sgabeblack@google.com    sc_process_handle &operator = (const sc_process_handle &);
17612838Sgabeblack@google.com    bool operator == (const sc_process_handle &) const;
17712838Sgabeblack@google.com    bool operator != (const sc_process_handle &) const;
17812838Sgabeblack@google.com    bool operator < (const sc_process_handle &) const;
17912952Sgabeblack@google.com    void swap(sc_process_handle &);
18012838Sgabeblack@google.com
18112838Sgabeblack@google.com    const char *name() const;
18212838Sgabeblack@google.com    sc_curr_proc_kind proc_kind() const;
18312838Sgabeblack@google.com    const std::vector<sc_object *> &get_child_objects() const;
18412838Sgabeblack@google.com    const std::vector<sc_event *> &get_child_events() const;
18512838Sgabeblack@google.com    sc_object *get_parent_object() const;
18612838Sgabeblack@google.com    sc_object *get_process_object() const;
18712838Sgabeblack@google.com    bool dynamic() const;
18812838Sgabeblack@google.com    bool terminated() const;
18912838Sgabeblack@google.com    const sc_event &terminated_event() const;
19012838Sgabeblack@google.com
19112838Sgabeblack@google.com    void suspend(sc_descendent_inclusion_info include_descendants=
19212838Sgabeblack@google.com                 SC_NO_DESCENDANTS);
19312838Sgabeblack@google.com    void resume(sc_descendent_inclusion_info include_descendants=
19412838Sgabeblack@google.com                SC_NO_DESCENDANTS);
19512838Sgabeblack@google.com    void disable(sc_descendent_inclusion_info include_descendants=
19612838Sgabeblack@google.com                 SC_NO_DESCENDANTS);
19712838Sgabeblack@google.com    void enable(sc_descendent_inclusion_info include_descendants=
19812838Sgabeblack@google.com                SC_NO_DESCENDANTS);
19912838Sgabeblack@google.com    void kill(sc_descendent_inclusion_info include_descendants=
20012838Sgabeblack@google.com              SC_NO_DESCENDANTS);
20112838Sgabeblack@google.com    void reset(sc_descendent_inclusion_info include_descendants=
20212838Sgabeblack@google.com               SC_NO_DESCENDANTS);
20312838Sgabeblack@google.com    bool is_unwinding();
20412838Sgabeblack@google.com    const sc_event &reset_event() const;
20512838Sgabeblack@google.com
20612838Sgabeblack@google.com    void sync_reset_on(sc_descendent_inclusion_info include_descendants=
20712838Sgabeblack@google.com                       SC_NO_DESCENDANTS);
20812838Sgabeblack@google.com    void sync_reset_off(sc_descendent_inclusion_info include_descendants=
20912838Sgabeblack@google.com                        SC_NO_DESCENDANTS);
21012838Sgabeblack@google.com
21112838Sgabeblack@google.com    template <typename T>
21212952Sgabeblack@google.com    void
21312952Sgabeblack@google.com    throw_it(const T &user_defined_exception,
21412952Sgabeblack@google.com             sc_descendent_inclusion_info include_descendants=
21512952Sgabeblack@google.com             SC_NO_DESCENDANTS)
21612838Sgabeblack@google.com    {
21713128Sgabeblack@google.com        if (!_gem5_process) {
21813317Sgabeblack@google.com            SC_REPORT_WARNING(SC_ID_EMPTY_PROCESS_HANDLE_, "throw_it()");
21913128Sgabeblack@google.com            return;
22013128Sgabeblack@google.com        }
22112952Sgabeblack@google.com        ::sc_gem5::ExceptionWrapper<T> exc(user_defined_exception);
22212952Sgabeblack@google.com        ::sc_gem5::throw_it_wrapper(_gem5_process, exc,
22312952Sgabeblack@google.com                include_descendants == SC_INCLUDE_DESCENDANTS);
22412838Sgabeblack@google.com    }
22512838Sgabeblack@google.com};
22612838Sgabeblack@google.com
22712838Sgabeblack@google.comsc_process_handle sc_get_current_process_handle();
22812838Sgabeblack@google.combool sc_is_unwinding();
22912838Sgabeblack@google.com
23012899Sgabeblack@google.com// Nonstandard
23112899Sgabeblack@google.com// See Accellera's kernel/sim_context.cpp for an explanation of what this is
23212899Sgabeblack@google.com// supposed to do. It essentially selects what happens during certain
23312899Sgabeblack@google.com// undefined situations.
23412899Sgabeblack@google.comextern bool sc_allow_process_control_corners;
23512899Sgabeblack@google.com
23612838Sgabeblack@google.com} // namespace sc_core
23712838Sgabeblack@google.com
23812838Sgabeblack@google.com#endif  //__SYSTEMC_EXT_CORE_SC_PROCESS_HANDLE_HH__
239