sc_spawn.hh revision 13196
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 // Disabled 134 sc_spawn_options(const sc_spawn_options &) {} 135 sc_spawn_options &operator = (const sc_spawn_options &) { return *this; } 136}; 137 138void sc_spawn_warn_unimpl(const char *func); 139 140template <typename T> 141sc_process_handle 142sc_spawn(T object, const char *name_p=nullptr, 143 const sc_spawn_options *opt_p=nullptr) 144{ 145 auto func = new ::sc_gem5::ProcessObjFuncWrapper<T>(object); 146 ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p); 147 return sc_process_handle() = p; 148} 149 150template <typename T> 151sc_process_handle 152sc_spawn(typename T::result_type *r_p, T object, const char *name_p=nullptr, 153 const sc_spawn_options *opt_p=nullptr) 154{ 155 auto func = new ::sc_gem5::ProcessObjRetFuncWrapper< 156 T, typename T::result_type>(object, r_p); 157 ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p); 158 return sc_process_handle() = p; 159} 160 161#define sc_bind boost::bind 162#define sc_ref(r) boost::ref(r) 163#define sc_cref(r) boost::cref(r) 164 165#define SC_FORK \ 166{ \ 167 ::sc_core::sc_process_handle forkees[] = { 168 169#define SC_JOIN \ 170 }; \ 171 ::sc_core::sc_join join; \ 172 for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \ 173 join.add_process(forkees[i]); \ 174 join.wait(); \ 175} 176 177// Non-standard 178#define SC_CJOIN \ 179 }; \ 180 ::sc_core::sc_join join; \ 181 for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \ 182 join.add_process(forkees[i]); \ 183 join.wait_clocked(); \ 184} 185 186 187} // namespace sc_core 188 189namespace sc_unnamed 190{ 191 192typedef int ImplementationDefined; 193extern ImplementationDefined _1; 194extern ImplementationDefined _2; 195extern ImplementationDefined _3; 196extern ImplementationDefined _4; 197extern ImplementationDefined _5; 198extern ImplementationDefined _6; 199extern ImplementationDefined _7; 200extern ImplementationDefined _8; 201extern ImplementationDefined _9; 202 203} // namespace sc_unnamed 204 205#endif //__SYSTEMC_EXT_CORE_SC_SPAWN_HH__ 206