00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00037 #include "rc_control.h"
00038
00039 namespace ReChannel {
00040
00041 bool rc_control::has_control(
00042 const rc_reconfigurable_set& reconf_set) const
00043 {
00044 rc_reconfigurable_set::const_iterator it;
00045 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00046 rc_reconfigurable& reconf = *(*it);
00047 if (p_reconfigurable_set.find(reconf)
00048 == p_reconfigurable_set.end()) {
00049 return false;
00050 }
00051 }
00052 return true;
00053 }
00054
00055 void rc_control::add(const rc_reconfigurable_set& reconf_set)
00056 {
00057 rc_reconfigurable_set::const_iterator it;
00058 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00059 rc_reconfigurable& reconf = *(*it);
00060 rc_control* owner = reconf.get_control();
00061 if (owner != NULL && owner != this) {
00062 RC_REPORT_ERROR(RC_ID_CONTROL_CONFLICT_,
00063 "dynamic object '" << reconf.rc_get_name()
00064 << "' still controlled by control '"
00065 << owner->name() << "' (in control '"
00066 << this->name() << "'");
00067 }
00068
00069 reconf.set_control(this);
00070
00071 for (int i=0; i < rc_reconfigurable::ACTION_COUNT; i++) {
00072 typedef rc_reconfigurable::action_type action_type;
00073 reconf.rc_set_delay(
00074 (action_type)i, takes_time(reconf, (action_type)i));
00075 }
00076 p_reconfigurable_set.insert(reconf);
00077 sc_object* obj = reconf.rc_get_object();
00078 if (obj != NULL) {
00079 p_obj_reconf_map.insert(
00080 obj_reconf_map::value_type(obj, &reconf));
00081 }
00082 }
00083 }
00084
00085 void rc_control::remove(const rc_reconfigurable_set& reconf_set)
00086 {
00087 lock(reconf_set);
00088 try {
00089 unload(reconf_set);
00090 rc_reconfigurable_set::const_iterator it;
00091 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00092 rc_reconfigurable& reconf = *(*it);
00093 reconf.set_control(NULL);
00094 p_reconfigurable_set.erase(reconf);
00095 sc_object* obj = reconf.rc_get_object();
00096 if (obj != NULL) {
00097 p_obj_reconf_map.erase(obj);
00098 }
00099 }
00100 } catch(...) {
00101 unlock(reconf_set);
00102 throw;
00103 }
00104
00105 rc_reconfigurable_set::const_iterator it;
00106 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00107 rc_reconfigurable& reconf = *(*it);
00108
00109 while(reconf.unlock());
00110 }
00111
00112 }
00113
00114 void rc_control::load(const rc_reconfigurable_set& reconf_set)
00115 {
00116 _rc_do_action(
00117 reconf_set, rc_reconfigurable::INACTIVE,
00118 rc_reconfigurable::UNLOADED);
00119 }
00120
00121 void rc_control::unload(const rc_reconfigurable_set& reconf_set)
00122 {
00123 _rc_do_action(reconf_set, rc_reconfigurable::UNLOADED);
00124 }
00125
00126 void rc_control::activate(const rc_reconfigurable_set& reconf_set)
00127 {
00128 _rc_do_action(reconf_set, rc_reconfigurable::ACTIVE);
00129 }
00130
00131 void rc_control::deactivate(const rc_reconfigurable_set& reconf_set)
00132 {
00133 _rc_do_action(
00134 reconf_set, rc_reconfigurable::INACTIVE,
00135 rc_reconfigurable::ACTIVE);
00136 }
00137
00138 void rc_control::move(
00139 const rc_reconfigurable_set& reconf_set,
00140 rc_switch_connector_base& target)
00141 {
00142 lock(reconf_set);
00143 try {
00144 unload(reconf_set);
00145 rc_reconfigurable_set::const_iterator it;
00146 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00147 rc_reconfigurable& reconf = *(*it);
00148 reconf.move(target);
00149 }
00150 } catch(...) {
00151 unlock(reconf_set);
00152 throw;
00153 }
00154 unlock(reconf_set);
00155 }
00156
00157 void rc_control::lock(const rc_reconfigurable_set& reconf_set)
00158 {
00159 rc_reconfigurable_set::const_iterator it;
00160 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00161 rc_reconfigurable& reconf = *(*it);
00162 if (reconf.get_control() != this) {
00163
00164 _rc_unlock(reconf_set.begin(), it);
00165 RC_REPORT_ERROR(RC_ID_CONTROL_CONFLICT_,
00166 "no control over dynamic object '"
00167 << reconf.rc_get_name() << "' (in control '"
00168 << this->name() << "'");
00169 }
00170 reconf.lock();
00171 }
00172 }
00173
00174 bool rc_control::trylock(const rc_reconfigurable_set& reconf_set)
00175 {
00176 rc_reconfigurable_set::const_iterator it;
00177 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00178 rc_reconfigurable& reconf = *(*it);
00179 if (reconf.get_control() != this) {
00180
00181 _rc_unlock(reconf_set.begin(), it);
00182 RC_REPORT_ERROR(RC_ID_CONTROL_CONFLICT_,
00183 "no control over dynamic object '"
00184 << reconf.rc_get_name() << "' (in control '"
00185 << this->name() << "'");
00186 }
00187 if (!reconf.trylock()) {
00188
00189 _rc_unlock(reconf_set.begin(), it);
00190 return false;
00191 }
00192 }
00193 return true;
00194 }
00195
00196 void rc_control::unlock(const rc_reconfigurable_set& reconf_set)
00197 {
00198 _rc_unlock(reconf_set.begin(), reconf_set.end());
00199 }
00200
00201 bool rc_control::is_locked(const rc_reconfigurable_set& reconf_set) const
00202 {
00203 rc_reconfigurable_set::const_iterator it;
00204 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00205 rc_reconfigurable& reconf = *(*it);
00206 if (!reconf.is_locked()) {
00207 return false;
00208 }
00209 }
00210 return true;
00211 }
00212
00213 sc_time rc_control::takes_time(
00214 const rc_reconfigurable& reconf,
00215 rc_reconfigurable::action_type action) const
00216 {
00217 return reconf.rc_get_default_delay(action);
00218 }
00219
00220 void rc_control::update_delays(rc_reconfigurable::action_type action)
00221 {
00222
00223 rc_reconfigurable_set::const_iterator it;
00224 for(it = p_reconfigurable_set.begin();
00225 it != p_reconfigurable_set.end();
00226 ++it)
00227 {
00228 rc_reconfigurable& reconf = *(*it);
00229
00230 reconf.rc_set_delay(action, takes_time(reconf, action));
00231 }
00232 }
00233
00234 void rc_control::get_controlled_set(
00235 rc_reconfigurable_set& copy_dest) const
00236 {
00237 copy_dest = p_reconfigurable_set;
00238 }
00239
00240 void rc_control::start_of_simulation()
00241 {
00242 static bool s_start_of_simulation_called = false;
00243
00244
00245 if (!s_start_of_simulation_called) {
00246 std::vector<rc_reconfigurable*> all_reconfigurables;
00247 rc_reconfigurable::get_all_reconfigurables(all_reconfigurables);
00248 std::vector<rc_reconfigurable*>::const_iterator it;
00249 for(it = all_reconfigurables.begin();
00250 it != all_reconfigurables.end();
00251 ++it)
00252 {
00253 rc_reconfigurable& reconf = *(*it);
00254 reconf.start_of_simulation();
00255 }
00256 s_start_of_simulation_called = true;
00257 }
00258 }
00259
00260 void rc_control::_rc_unlock(
00261 rc_reconfigurable_set::const_iterator start_,
00262 rc_reconfigurable_set::const_iterator end_) const
00263 {
00264 rc_reconfigurable_set::const_iterator it;
00265 for(it = start_; it != end_; ++it) {
00266 rc_reconfigurable& reconf = *(*it);
00267 reconf.unlock();
00268 }
00269 }
00270
00271 void rc_control::_rc_do_action(
00272 const rc_reconfigurable_set& reconf_set,
00273 rc_reconfigurable::state_type new_state)
00274 {
00275 if (reconf_set.size() == 0) {
00276 return;
00277 }
00278 lock(reconf_set);
00279 try {
00280 _rc_reconfigure(reconf_set, new_state);
00281 } catch(...) {
00282 unlock(reconf_set);
00283 throw;
00284 }
00285 unlock(reconf_set);
00286 }
00287
00288 void rc_control::_rc_do_action(
00289 const rc_reconfigurable_set& reconf_set,
00290 rc_reconfigurable::state_type new_state,
00291 rc_reconfigurable::state_type only_change_state)
00292 {
00293 if (reconf_set.size() == 0) {
00294 return;
00295 }
00296 lock(reconf_set);
00297 try {
00298 rc_reconfigurable_set dyn_objects_to_change;
00299 rc_reconfigurable_set::const_iterator it;
00300 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00301 rc_reconfigurable& reconf = *(*it);
00302 if (reconf.rc_get_state() == only_change_state) {
00303 dyn_objects_to_change.insert(reconf);
00304 }
00305 }
00306 _rc_reconfigure(dyn_objects_to_change, new_state);
00307 } catch(...) {
00308 unlock(reconf_set);
00309 throw;
00310 }
00311 unlock(reconf_set);
00312 }
00313
00314 void rc_control::_rc_reconfigure(
00315 const rc_reconfigurable_set& reconf_set,
00316 rc_reconfigurable::state_type new_state)
00317 {
00318 if (sc_is_running()) {
00319 if (reconf_set.size() == 0) {
00320 return;
00321 } else if (reconf_set.size() == 1) {
00322 rc_reconfigurable& reconf = *(*(reconf_set.begin()));
00323 if (reconf.rc_get_state() != new_state) {
00324 reconf.reconfigure(new_state);
00325 }
00326 } else {
00327 typedef std::vector<sc_process_handle> proc_vector_type;
00328 proc_vector_type procs;
00329 rc_reconfigurable_set::const_iterator it;
00330 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00331 rc_reconfigurable& reconf = *(*it);
00332 if (reconf.rc_get_state() != new_state) {
00333 sc_process_handle proc =
00334 sc_spawn(
00335 sc_bind(
00336 &rc_reconfigurable::reconfigure,
00337 &reconf, new_state));
00338 reconf.share_lock(proc);
00339 procs.push_back(proc);
00340 }
00341 }
00342 if (procs.size() > 0) {
00343 if (procs.size() == 1) {
00344 ::sc_core::wait((*procs.begin()).terminated_event());
00345 } else {
00346 sc_event_and_list& event_and_list =
00347 (*procs.begin()).terminated_event()
00348 & (*(++procs.begin())).terminated_event();
00349 proc_vector_type::iterator it;
00350 for(it = procs.begin() + 3; it != procs.end(); ++it) {
00351 event_and_list & (*it).terminated_event();
00352 }
00353 ::sc_core::wait(event_and_list);
00354 }
00355 }
00356 }
00357 } else {
00358 rc_reconfigurable_set::const_iterator it;
00359 for(it = reconf_set.begin(); it != reconf_set.end(); ++it) {
00360 rc_reconfigurable& reconf = *(*it);
00361
00362 reconf.reconfigure(new_state);
00363 }
00364 }
00365 }
00366
00367 }
00368
00369
00370
00371
00372