sc_spawn.hh revision 13260:4d18f1d20093
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#ifndef __SYSTEMC_EXT_CORE_SC_SPAWN_HH__
31#define __SYSTEMC_EXT_CORE_SC_SPAWN_HH__
32
33#include <vector>
34
35#include "sc_join.hh"
36#include "sc_process_handle.hh"
37
38namespace sc_core
39{
40
41class sc_spawn_options;
42
43} // namespace sc_core
44
45namespace sc_gem5
46{
47
48class Process;
49
50template <typename T>
51struct ProcessObjFuncWrapper : public ProcessFuncWrapper
52{
53    T t;
54
55    ProcessObjFuncWrapper(T t) : t(t) {}
56
57    void call() override { t(); }
58};
59
60template <typename T, typename R>
61struct ProcessObjRetFuncWrapper : public ProcessFuncWrapper
62{
63    T t;
64    R *r;
65
66    ProcessObjRetFuncWrapper(T t, R *r) : t(t), r(r) {}
67
68    void call() override { *r = t(); }
69};
70
71Process *spawnWork(ProcessFuncWrapper *func, const char *name,
72                   const ::sc_core::sc_spawn_options *);
73
74} // namespace sc_gem5
75
76namespace sc_core
77{
78
79template <class T>
80class sc_in;
81template <class T>
82class sc_inout;
83template <class T>
84class sc_out;
85template <class T>
86class sc_signal_in_if;
87
88class sc_event;
89class sc_event_finder;
90class sc_export_base;
91class sc_interface;
92class sc_port_base;
93
94class sc_spawn_options
95{
96  public:
97    friend ::sc_gem5::Process *::sc_gem5::spawnWork(
98            ::sc_gem5::ProcessFuncWrapper *, const char *,
99            const sc_spawn_options *);
100
101    sc_spawn_options();
102
103    void spawn_method();
104    void dont_initialize();
105    void set_stack_size(int);
106
107    void set_sensitivity(const sc_event *);
108    void set_sensitivity(sc_port_base *);
109    void set_sensitivity(sc_export_base *);
110    void set_sensitivity(sc_interface *);
111    void set_sensitivity(sc_event_finder *);
112
113    void reset_signal_is(const sc_in<bool> &, bool);
114    void reset_signal_is(const sc_inout<bool> &, bool);
115    void reset_signal_is(const sc_out<bool> &, bool);
116    void reset_signal_is(const sc_signal_in_if<bool> &, bool);
117
118    void async_reset_signal_is(const sc_in<bool> &, bool);
119    void async_reset_signal_is(const sc_inout<bool> &, bool);
120    void async_reset_signal_is(const sc_out<bool> &, bool);
121    void async_reset_signal_is(const sc_signal_in_if<bool> &, bool);
122
123  private:
124    bool _spawnMethod;
125    bool _dontInitialize;
126    int _stackSize;
127    std::vector<const sc_event *> _events;
128    std::vector<sc_port_base *> _ports;
129    std::vector<sc_export_base *> _exports;
130    std::vector<sc_interface *> _interfaces;
131    std::vector<sc_event_finder *> _finders;
132
133    template <typename T>
134    struct Reset
135    {
136        Reset(T *t, bool v, bool s) : target(t), value(v), sync(s) {}
137
138        T *target;
139        bool value;
140        bool sync;
141    };
142
143    std::vector<Reset<const sc_in<bool> > > _in_resets;
144    std::vector<Reset<const sc_inout<bool> > > _inout_resets;
145    std::vector<Reset<const sc_out<bool> > > _out_resets;
146    std::vector<Reset<const sc_signal_in_if<bool> > > _if_resets;
147
148    // Disabled
149    sc_spawn_options(const sc_spawn_options &) {}
150    sc_spawn_options &operator = (const sc_spawn_options &) { return *this; }
151};
152
153void sc_spawn_warn_unimpl(const char *func);
154
155template <typename T>
156sc_process_handle
157sc_spawn(T object, const char *name_p=nullptr,
158         const sc_spawn_options *opt_p=nullptr)
159{
160    auto func = new ::sc_gem5::ProcessObjFuncWrapper<T>(object);
161    ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p);
162    return sc_process_handle() = p;
163}
164
165template <typename T>
166sc_process_handle
167sc_spawn(typename T::result_type *r_p, T object, const char *name_p=nullptr,
168         const sc_spawn_options *opt_p=nullptr)
169{
170    auto func = new ::sc_gem5::ProcessObjRetFuncWrapper<
171        T, typename T::result_type>(object, r_p);
172    ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p);
173    return sc_process_handle() = p;
174}
175
176#define sc_bind boost::bind
177#define sc_ref(r) boost::ref(r)
178#define sc_cref(r) boost::cref(r)
179
180#define SC_FORK \
181{ \
182    ::sc_core::sc_process_handle forkees[] = {
183
184#define SC_JOIN \
185    }; \
186    ::sc_core::sc_join join; \
187    for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \
188        join.add_process(forkees[i]); \
189    join.wait(); \
190}
191
192// Non-standard
193#define SC_CJOIN \
194    }; \
195    ::sc_core::sc_join join; \
196    for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \
197        join.add_process(forkees[i]); \
198    join.wait_clocked(); \
199}
200
201
202} // namespace sc_core
203
204namespace sc_unnamed
205{
206
207typedef int ImplementationDefined;
208extern ImplementationDefined _1;
209extern ImplementationDefined _2;
210extern ImplementationDefined _3;
211extern ImplementationDefined _4;
212extern ImplementationDefined _5;
213extern ImplementationDefined _6;
214extern ImplementationDefined _7;
215extern ImplementationDefined _8;
216extern ImplementationDefined _9;
217
218} // namespace sc_unnamed
219
220#endif  //__SYSTEMC_EXT_CORE_SC_SPAWN_HH__
221