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#include "base/logging.hh" 31#include "systemc/core/process.hh" 32#include "systemc/core/process_types.hh" 33#include "systemc/core/scheduler.hh" 34#include "systemc/ext/channel/sc_in.hh" 35#include "systemc/ext/channel/sc_inout.hh" 36#include "systemc/ext/channel/sc_out.hh" 37#include "systemc/ext/channel/sc_signal_in_if.hh" 38#include "systemc/ext/core/messages.hh" 39#include "systemc/ext/core/sc_main.hh" 40#include "systemc/ext/core/sc_module.hh" 41#include "systemc/ext/core/sc_spawn.hh" 42 43namespace sc_gem5 44{ 45 46Process * 47spawnWork(ProcessFuncWrapper *func, const char *name, 48 const ::sc_core::sc_spawn_options *opts) 49{ 50 bool method = false; 51 bool dontInitialize = false; 52 if (opts) { 53 if (opts->_spawnMethod) 54 method = true; 55 if (opts->_dontInitialize) 56 dontInitialize = true; 57 if (opts->_stackSize != -1) 58 warn("Ignoring request to set stack size.\n"); 59 } 60 61 if (!name || name[0] == '\0') { 62 if (method) 63 name = ::sc_core::sc_gen_unique_name("method_p"); 64 else 65 name = ::sc_core::sc_gen_unique_name("thread_p"); 66 } 67 68 Process *proc; 69 if (method) 70 proc = new Method(name, func); 71 else 72 proc = new Thread(name, func); 73 74 proc->dontInitialize(dontInitialize); 75 76 if (opts) { 77 for (auto e: opts->_events) 78 newStaticSensitivityEvent(proc, e); 79 80 for (auto p: opts->_ports) 81 newStaticSensitivityPort(proc, p); 82 83 for (auto e: opts->_exports) 84 newStaticSensitivityExport(proc, e); 85 86 for (auto i: opts->_interfaces) 87 newStaticSensitivityInterface(proc, i); 88 89 for (auto f: opts->_finders) 90 newStaticSensitivityFinder(proc, f); 91 92 for (auto p: opts->_in_resets) 93 newReset(p.target, proc, p.sync, p.value); 94 95 for (auto p: opts->_inout_resets) 96 newReset(p.target, proc, p.sync, p.value); 97 98 for (auto p: opts->_out_resets) 99 newReset(p.target, proc, p.sync, p.value); 100 101 for (auto i: opts->_if_resets) 102 newReset(i.target, proc, i.sync, i.value); 103 } 104 105 if (opts && opts->_dontInitialize && 106 opts->_events.empty() && opts->_ports.empty() && 107 opts->_exports.empty() && opts->_interfaces.empty() && 108 opts->_finders.empty()) { 109 SC_REPORT_WARNING(sc_core::SC_ID_DISABLE_WILL_ORPHAN_PROCESS_, 110 proc->name()); 111 } 112 113 scheduler.reg(proc); 114 115 return proc; 116} 117 118} // namespace sc_gem5 119 120namespace sc_core 121{ 122 123sc_spawn_options::sc_spawn_options() : 124 _spawnMethod(false), _dontInitialize(false), _stackSize(-1) 125{} 126 127 128void 129sc_spawn_options::spawn_method() 130{ 131 _spawnMethod = true; 132} 133 134void 135sc_spawn_options::dont_initialize() 136{ 137 _dontInitialize = true; 138} 139 140void 141sc_spawn_options::set_stack_size(int ss) 142{ 143 _stackSize = ss; 144} 145 146 147void 148sc_spawn_options::set_sensitivity(const sc_event *e) 149{ 150 _events.push_back(e); 151} 152 153void 154sc_spawn_options::set_sensitivity(sc_port_base *p) 155{ 156 _ports.push_back(p); 157} 158 159void 160sc_spawn_options::set_sensitivity(sc_export_base *e) 161{ 162 _exports.push_back(e); 163} 164 165void 166sc_spawn_options::set_sensitivity(sc_interface *i) 167{ 168 _interfaces.push_back(i); 169} 170 171void 172sc_spawn_options::set_sensitivity(sc_event_finder *f) 173{ 174 _finders.push_back(f); 175} 176 177 178void 179sc_spawn_options::reset_signal_is(const sc_in<bool> &port, bool value) 180{ 181 _in_resets.emplace_back(&port, value, true); 182} 183 184void 185sc_spawn_options::reset_signal_is(const sc_inout<bool> &port, bool value) 186{ 187 _inout_resets.emplace_back(&port, value, true); 188} 189 190void 191sc_spawn_options::reset_signal_is(const sc_out<bool> &port, bool value) 192{ 193 _out_resets.emplace_back(&port, value, true); 194} 195 196void 197sc_spawn_options::reset_signal_is( 198 const sc_signal_in_if<bool> &iface, bool value) 199{ 200 _if_resets.emplace_back(&iface, value, true); 201} 202 203 204void 205sc_spawn_options::async_reset_signal_is(const sc_in<bool> &port, bool value) 206{ 207 _in_resets.emplace_back(&port, value, false); 208} 209 210void 211sc_spawn_options::async_reset_signal_is(const sc_inout<bool> &port, bool value) 212{ 213 _inout_resets.emplace_back(&port, value, false); 214} 215 216void 217sc_spawn_options::async_reset_signal_is(const sc_out<bool> &port, bool value) 218{ 219 _out_resets.emplace_back(&port, value, false); 220} 221 222void 223sc_spawn_options::async_reset_signal_is( 224 const sc_signal_in_if<bool> &iface, bool value) 225{ 226 _if_resets.emplace_back(&iface, value, false); 227} 228 229} // namespace sc_core 230