112839Sgabeblack@google.com/* 212839Sgabeblack@google.com * Copyright 2018 Google, Inc. 312839Sgabeblack@google.com * 412839Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512839Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612839Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712839Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812839Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912839Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012839Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112839Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212839Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312839Sgabeblack@google.com * this software without specific prior written permission. 1412839Sgabeblack@google.com * 1512839Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612839Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712839Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812839Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912839Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012839Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112839Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212839Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312839Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412839Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512839Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612839Sgabeblack@google.com * 2712839Sgabeblack@google.com * Authors: Gabe Black 2812839Sgabeblack@google.com */ 2912839Sgabeblack@google.com 3012839Sgabeblack@google.com#ifndef __SYSTEMC_EXT_CORE_SC_SPAWN_HH__ 3112839Sgabeblack@google.com#define __SYSTEMC_EXT_CORE_SC_SPAWN_HH__ 3212839Sgabeblack@google.com 3313267Sgabeblack@google.com#include <functional> 3412993Sgabeblack@google.com#include <vector> 3512993Sgabeblack@google.com 3613196Sgabeblack@google.com#include "sc_join.hh" 3712839Sgabeblack@google.com#include "sc_process_handle.hh" 3812839Sgabeblack@google.com 3912839Sgabeblack@google.comnamespace sc_core 4012839Sgabeblack@google.com{ 4112839Sgabeblack@google.com 4212993Sgabeblack@google.comclass sc_spawn_options; 4312993Sgabeblack@google.com 4412993Sgabeblack@google.com} // namespace sc_core 4512993Sgabeblack@google.com 4612993Sgabeblack@google.comnamespace sc_gem5 4712993Sgabeblack@google.com{ 4812993Sgabeblack@google.com 4912993Sgabeblack@google.comclass Process; 5012993Sgabeblack@google.com 5112993Sgabeblack@google.comtemplate <typename T> 5212993Sgabeblack@google.comstruct ProcessObjFuncWrapper : public ProcessFuncWrapper 5312993Sgabeblack@google.com{ 5412993Sgabeblack@google.com T t; 5512993Sgabeblack@google.com 5612993Sgabeblack@google.com ProcessObjFuncWrapper(T t) : t(t) {} 5712993Sgabeblack@google.com 5812993Sgabeblack@google.com void call() override { t(); } 5912993Sgabeblack@google.com}; 6012993Sgabeblack@google.com 6112993Sgabeblack@google.comtemplate <typename T, typename R> 6212993Sgabeblack@google.comstruct ProcessObjRetFuncWrapper : public ProcessFuncWrapper 6312993Sgabeblack@google.com{ 6412993Sgabeblack@google.com T t; 6512993Sgabeblack@google.com R *r; 6612993Sgabeblack@google.com 6712993Sgabeblack@google.com ProcessObjRetFuncWrapper(T t, R *r) : t(t), r(r) {} 6812993Sgabeblack@google.com 6912993Sgabeblack@google.com void call() override { *r = t(); } 7012993Sgabeblack@google.com}; 7112993Sgabeblack@google.com 7212993Sgabeblack@google.comProcess *spawnWork(ProcessFuncWrapper *func, const char *name, 7312993Sgabeblack@google.com const ::sc_core::sc_spawn_options *); 7412993Sgabeblack@google.com 7512993Sgabeblack@google.com} // namespace sc_gem5 7612993Sgabeblack@google.com 7712993Sgabeblack@google.comnamespace sc_core 7812993Sgabeblack@google.com{ 7912993Sgabeblack@google.com 8012839Sgabeblack@google.comtemplate <class T> 8112839Sgabeblack@google.comclass sc_in; 8212839Sgabeblack@google.comtemplate <class T> 8312839Sgabeblack@google.comclass sc_inout; 8412839Sgabeblack@google.comtemplate <class T> 8512839Sgabeblack@google.comclass sc_out; 8612839Sgabeblack@google.comtemplate <class T> 8712839Sgabeblack@google.comclass sc_signal_in_if; 8812839Sgabeblack@google.com 8912839Sgabeblack@google.comclass sc_event; 9012839Sgabeblack@google.comclass sc_event_finder; 9112839Sgabeblack@google.comclass sc_export_base; 9212839Sgabeblack@google.comclass sc_interface; 9312839Sgabeblack@google.comclass sc_port_base; 9412839Sgabeblack@google.com 9512839Sgabeblack@google.comclass sc_spawn_options 9612839Sgabeblack@google.com{ 9712839Sgabeblack@google.com public: 9812993Sgabeblack@google.com friend ::sc_gem5::Process *::sc_gem5::spawnWork( 9912993Sgabeblack@google.com ::sc_gem5::ProcessFuncWrapper *, const char *, 10012993Sgabeblack@google.com const sc_spawn_options *); 10112993Sgabeblack@google.com 10212839Sgabeblack@google.com sc_spawn_options(); 10312839Sgabeblack@google.com 10412839Sgabeblack@google.com void spawn_method(); 10512839Sgabeblack@google.com void dont_initialize(); 10612839Sgabeblack@google.com void set_stack_size(int); 10712839Sgabeblack@google.com 10812839Sgabeblack@google.com void set_sensitivity(const sc_event *); 10912839Sgabeblack@google.com void set_sensitivity(sc_port_base *); 11012839Sgabeblack@google.com void set_sensitivity(sc_export_base *); 11112839Sgabeblack@google.com void set_sensitivity(sc_interface *); 11212839Sgabeblack@google.com void set_sensitivity(sc_event_finder *); 11312839Sgabeblack@google.com 11412839Sgabeblack@google.com void reset_signal_is(const sc_in<bool> &, bool); 11512839Sgabeblack@google.com void reset_signal_is(const sc_inout<bool> &, bool); 11612839Sgabeblack@google.com void reset_signal_is(const sc_out<bool> &, bool); 11712839Sgabeblack@google.com void reset_signal_is(const sc_signal_in_if<bool> &, bool); 11812839Sgabeblack@google.com 11912839Sgabeblack@google.com void async_reset_signal_is(const sc_in<bool> &, bool); 12012839Sgabeblack@google.com void async_reset_signal_is(const sc_inout<bool> &, bool); 12112839Sgabeblack@google.com void async_reset_signal_is(const sc_out<bool> &, bool); 12212839Sgabeblack@google.com void async_reset_signal_is(const sc_signal_in_if<bool> &, bool); 12312839Sgabeblack@google.com 12412839Sgabeblack@google.com private: 12512993Sgabeblack@google.com bool _spawnMethod; 12612993Sgabeblack@google.com bool _dontInitialize; 12712993Sgabeblack@google.com int _stackSize; 12812993Sgabeblack@google.com std::vector<const sc_event *> _events; 12912993Sgabeblack@google.com std::vector<sc_port_base *> _ports; 13012993Sgabeblack@google.com std::vector<sc_export_base *> _exports; 13112993Sgabeblack@google.com std::vector<sc_interface *> _interfaces; 13212993Sgabeblack@google.com std::vector<sc_event_finder *> _finders; 13312993Sgabeblack@google.com 13413260Sgabeblack@google.com template <typename T> 13513260Sgabeblack@google.com struct Reset 13613260Sgabeblack@google.com { 13713260Sgabeblack@google.com Reset(T *t, bool v, bool s) : target(t), value(v), sync(s) {} 13813260Sgabeblack@google.com 13913260Sgabeblack@google.com T *target; 14013260Sgabeblack@google.com bool value; 14113260Sgabeblack@google.com bool sync; 14213260Sgabeblack@google.com }; 14313260Sgabeblack@google.com 14413260Sgabeblack@google.com std::vector<Reset<const sc_in<bool> > > _in_resets; 14513260Sgabeblack@google.com std::vector<Reset<const sc_inout<bool> > > _inout_resets; 14613260Sgabeblack@google.com std::vector<Reset<const sc_out<bool> > > _out_resets; 14713260Sgabeblack@google.com std::vector<Reset<const sc_signal_in_if<bool> > > _if_resets; 14813260Sgabeblack@google.com 14912839Sgabeblack@google.com // Disabled 15012839Sgabeblack@google.com sc_spawn_options(const sc_spawn_options &) {} 15112839Sgabeblack@google.com sc_spawn_options &operator = (const sc_spawn_options &) { return *this; } 15212839Sgabeblack@google.com}; 15312839Sgabeblack@google.com 15412839Sgabeblack@google.comtemplate <typename T> 15512839Sgabeblack@google.comsc_process_handle 15612839Sgabeblack@google.comsc_spawn(T object, const char *name_p=nullptr, 15712839Sgabeblack@google.com const sc_spawn_options *opt_p=nullptr) 15812839Sgabeblack@google.com{ 15912993Sgabeblack@google.com auto func = new ::sc_gem5::ProcessObjFuncWrapper<T>(object); 16012993Sgabeblack@google.com ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p); 16112993Sgabeblack@google.com return sc_process_handle() = p; 16212839Sgabeblack@google.com} 16312839Sgabeblack@google.com 16412839Sgabeblack@google.comtemplate <typename T> 16512839Sgabeblack@google.comsc_process_handle 16612839Sgabeblack@google.comsc_spawn(typename T::result_type *r_p, T object, const char *name_p=nullptr, 16712839Sgabeblack@google.com const sc_spawn_options *opt_p=nullptr) 16812839Sgabeblack@google.com{ 16912993Sgabeblack@google.com auto func = new ::sc_gem5::ProcessObjRetFuncWrapper< 17012993Sgabeblack@google.com T, typename T::result_type>(object, r_p); 17112993Sgabeblack@google.com ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p); 17212993Sgabeblack@google.com return sc_process_handle() = p; 17312839Sgabeblack@google.com} 17412839Sgabeblack@google.com 17512879Sgabeblack@google.com#define SC_FORK \ 17612879Sgabeblack@google.com{ \ 17712879Sgabeblack@google.com ::sc_core::sc_process_handle forkees[] = { 17812879Sgabeblack@google.com 17912879Sgabeblack@google.com#define SC_JOIN \ 18013196Sgabeblack@google.com }; \ 18113196Sgabeblack@google.com ::sc_core::sc_join join; \ 18213196Sgabeblack@google.com for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \ 18313196Sgabeblack@google.com join.add_process(forkees[i]); \ 18413196Sgabeblack@google.com join.wait(); \ 18512879Sgabeblack@google.com} 18612879Sgabeblack@google.com 18712879Sgabeblack@google.com// Non-standard 18813196Sgabeblack@google.com#define SC_CJOIN \ 18913196Sgabeblack@google.com }; \ 19013196Sgabeblack@google.com ::sc_core::sc_join join; \ 19113196Sgabeblack@google.com for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \ 19213196Sgabeblack@google.com join.add_process(forkees[i]); \ 19313196Sgabeblack@google.com join.wait_clocked(); \ 19413196Sgabeblack@google.com} 19513196Sgabeblack@google.com 19613267Sgabeblack@google.com// This avoids boost introduces a dependency on c++11. If that's a problem, 19713267Sgabeblack@google.com// we could imitate Accellera and pick which one to use on the fly. 19813267Sgabeblack@google.com 19913267Sgabeblack@google.comtemplate <typename F, typename... Args> 20013267Sgabeblack@google.comauto sc_bind(F &&f, Args && ...args) -> 20113267Sgabeblack@google.com decltype(std::bind(std::forward<F>(f), std::forward<Args>(args)...)) 20213267Sgabeblack@google.com{ 20313267Sgabeblack@google.com return std::bind(std::forward<F>(f), std::forward<Args>(args)...); 20413267Sgabeblack@google.com} 20513267Sgabeblack@google.com 20613267Sgabeblack@google.comtemplate <typename T> 20713267Sgabeblack@google.comauto sc_ref(T &&v) -> decltype(std::ref(std::forward<T>(v))) 20813267Sgabeblack@google.com{ 20913267Sgabeblack@google.com return std::ref(std::forward<T>(v)); 21013267Sgabeblack@google.com} 21113267Sgabeblack@google.com 21213267Sgabeblack@google.comtemplate <typename T> 21313267Sgabeblack@google.comauto sc_cref(T &&v) -> decltype(std::cref(std::forward<T>(v))) 21413267Sgabeblack@google.com{ 21513267Sgabeblack@google.com return std::cref(std::forward<T>(v)); 21613267Sgabeblack@google.com} 21712839Sgabeblack@google.com 21812839Sgabeblack@google.com} // namespace sc_core 21912839Sgabeblack@google.com 22013267Sgabeblack@google.comusing sc_core::sc_bind; 22113267Sgabeblack@google.comusing sc_core::sc_ref; 22213267Sgabeblack@google.comusing sc_core::sc_cref; 22313267Sgabeblack@google.com 22412839Sgabeblack@google.comnamespace sc_unnamed 22512839Sgabeblack@google.com{ 22612839Sgabeblack@google.com 22713267Sgabeblack@google.comusing namespace std::placeholders; 22812839Sgabeblack@google.com 22912839Sgabeblack@google.com} // namespace sc_unnamed 23012839Sgabeblack@google.com 23112839Sgabeblack@google.com#endif //__SYSTEMC_EXT_CORE_SC_SPAWN_HH__ 232