rc_abstract_interface_wrapper.cpp

Go to the documentation of this file.
00001 // vim:set et sts=4 ts=4 tw=75 sw=4 ai ci cin cino=g0,t0:
00002 /*
00003  * Copyright (C) 2007, Technical Computer Science Group,
00004  *                     University of Bonn
00005  *
00006  * This file is part of the ReChannel library.
00007  *
00008  * The ReChannel library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the
00011  * License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be
00014  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this library; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
00021  * Boston, MA 02110-1301, USA.
00022  *
00023  * Authors: Andreas Raabe and Armin Felke. Implementation by Armin Felke.
00024  *          {raabe, felke}@cs.uni-bonn.de
00025  */
00037 #include "rc_abstract_interface_wrapper.h"
00038 
00039 namespace ReChannel {
00040 
00041 rc_abstract_interface_wrapper_b::event_ef_map
00042     rc_abstract_interface_wrapper_b::s_event_ef_map;
00043 
00044 rc_abstract_interface_wrapper_b::rc_abstract_interface_wrapper_b(void* if_)
00045     : p_interface(if_)
00046 { }
00047 
00048 rc_abstract_interface_wrapper_b::~rc_abstract_interface_wrapper_b()
00049 {
00050     event_forwarder_base_map::iterator it;
00051     for(it = p_event_forwarder_base_map.begin();
00052         it != p_event_forwarder_base_map.end(); it++) {
00053         delete it->second;
00054     }
00055     p_event_forwarder_base_map.clear();
00056 }
00057 
00058 void rc_abstract_interface_wrapper_b::missing_fallback_if_error() const
00059 {
00060     RC_REPORT_ERROR(RC_ID_FALLBACK_INTERFACE_MISSING_,
00061         "a fallback interface doesn't exist (in interface wrapper '"
00062         << get_interface_wrapper_name() << "')");
00063 }
00064 
00065 void rc_abstract_interface_wrapper_b::set_wrapped_if(void* if_)
00066 {
00067     p_interface = if_;
00068 
00069     // update blocking driver's channel reference
00070     for (vector::iterator it =
00071         p_drv_obj_vector.begin();
00072         it != p_drv_obj_vector.end();
00073         it++)
00074     {
00075         void* drv = *it;
00076         if (drv != NULL) {
00077             this->_rc_set_driver_channel(drv, if_);
00078         }
00079     }
00080     // update non-blocking driver's channel reference
00081     for (vector::iterator it =
00082         p_nb_drv_obj_vector.begin();
00083         it != p_nb_drv_obj_vector.end();
00084         it++)
00085     {
00086         void* nb_drv = *it;
00087         if (nb_drv != NULL) {
00088             this->_rc_set_nb_driver_channel(nb_drv, if_);
00089         }
00090     }
00091 }
00092 
00093 void* rc_abstract_interface_wrapper_b::create_driver_object(int index)
00094 {
00095     if (index >= RC_INTERFACE_WRAPPER_MAX_DRIVER_COUNT) {
00096         RC_REPORT_ERROR(RC_ID_OUT_OF_BOUNDS_,
00097             "RC_INTERFACE_WRAPPER_MAX_DRIVER_COUNT has been exceeded"
00098             " (in interface wrapper '"
00099             << this->get_interface_wrapper_name() << "')");
00100     } else if (index < 0) {
00101         RC_REPORT_ERROR(RC_ID_OUT_OF_BOUNDS_,
00102             "driver index out of bounds"
00103             " (in interface wrapper '"
00104             << this->get_interface_wrapper_name() << "')");
00105     }
00106     if (index >= (int)p_drv_obj_vector.size()) {
00107         p_drv_obj_vector.resize(index + 1);
00108     }
00109     return (p_drv_obj_vector[index] =
00110         this->_rc_create_driver_object(p_interface));
00111 }
00112 
00113 void* rc_abstract_interface_wrapper_b::create_nb_driver_object(int index)
00114 {
00115     if (index >= RC_INTERFACE_WRAPPER_MAX_DRIVER_COUNT) {
00116         RC_REPORT_ERROR(RC_ID_OUT_OF_BOUNDS_,
00117             "RC_INTERFACE_WRAPPER_MAX_DRIVER_COUNT has been exceeded"
00118             " (in interface wrapper '"
00119             << this->get_interface_wrapper_name() << "')");
00120     } else if (index < 0) {
00121         RC_REPORT_ERROR(RC_ID_OUT_OF_BOUNDS_,
00122             "driver index out of bounds "
00123             " (in interface wrapper '"
00124             << this->get_interface_wrapper_name() << "')");
00125     }
00126     if (index >= (int)p_nb_drv_obj_vector.size()) {
00127         p_nb_drv_obj_vector.resize(index + 1);
00128     }
00129     return (p_nb_drv_obj_vector[index] =
00130         this->_rc_create_nb_driver_object(p_interface));
00131 }
00132 
00133 void rc_abstract_interface_wrapper_b::delete_all_drivers()
00134 {
00135     for(vector::iterator it = p_drv_obj_vector.begin();
00136         it != p_drv_obj_vector.end(); it++) {
00137         this->_rc_delete_driver_object(*it);
00138     }
00139     p_drv_obj_vector.clear();
00140 
00141     for(vector::iterator it = p_nb_drv_obj_vector.begin();
00142         it != p_nb_drv_obj_vector.end(); it++) {
00143         this->_rc_delete_nb_driver_object(*it);
00144     }
00145     p_nb_drv_obj_vector.clear();
00146 }
00147 
00148 void rc_abstract_interface_wrapper_b::delete_all_event_forwarders()
00149 {
00150     event_forwarder_base_map::iterator it;
00151     for(it = p_event_forwarder_base_map.begin();
00152         it != p_event_forwarder_base_map.end();
00153         it++)
00154     {
00155         delete it->second;
00156         // note: deleting the associated spawned process is not possible
00157     }
00158     p_event_forwarder_base_map.clear();
00159 }
00160 
00161 void rc_abstract_interface_wrapper_b::add_event_forwarder(
00162     rc_event_forwarder_base& forwarder, const sc_event& e,
00163     const std::string& event_name)
00164 {
00165     std::string _event_name(event_name);
00166     if (_event_name.empty()) {
00167         _event_name = sc_gen_unique_name("event");
00168     }
00169     rc_event_forwarder_base*& item_ref = 
00170         p_event_forwarder_base_map[_event_name];
00171     if (item_ref != NULL) {
00172         RC_REPORT_ERROR(RC_ID_DUPLICATE_ENTRY_,
00173             "event forwarder for event '" << _event_name
00174             << "' already exists"
00175             " (in interface wrapper '"
00176             << this->get_interface_wrapper_name() << "')");
00177     }
00178     item_ref = &forwarder;
00179     this->_rc_spawn_event_forwarder_process(forwarder, e);
00180 }
00181 
00182 void rc_abstract_interface_wrapper_b::add_event_forwarder_target(
00183     sc_interface& if_, rc_event_filter* filter)
00184 {
00185     event_forwarder_base_map::iterator it;
00186     for(it = p_event_forwarder_base_map.begin();
00187         it != p_event_forwarder_base_map.end();
00188         it++)
00189     { it->second->add_target(if_, filter); }
00190 }
00191 
00192 bool rc_abstract_interface_wrapper_b::add_event_forwarder_target(
00193     const std::string& event_name, sc_interface& if_,
00194     rc_event_filter* filter)
00195 {
00196     event_forwarder_base_map::iterator it =
00197         p_event_forwarder_base_map.find(event_name);
00198     if (it != p_event_forwarder_base_map.end()) {
00199         return it->second->add_target(if_, filter);
00200     } else {
00201         return false;
00202     }
00203 }
00204 
00205 void rc_abstract_interface_wrapper_b::clear_event_forwarder_targets()
00206 {
00207     event_forwarder_base_map::iterator it;
00208     for(it = p_event_forwarder_base_map.begin();
00209         it != p_event_forwarder_base_map.end();
00210         it++)
00211     { it->second->clear_targets(); }
00212 }
00213 
00214 void rc_abstract_interface_wrapper_b::clear_event_forwarder_targets(
00215     const std::string& event_name)
00216 {
00217     event_forwarder_base_map::iterator it =
00218         p_event_forwarder_base_map.find(event_name);
00219     if (it != p_event_forwarder_base_map.end()) {
00220         return it->second->clear_targets();
00221     }
00222 }
00223 
00224 rc_abstract_interface_wrapper_b::string_vector
00225 rc_abstract_interface_wrapper_b::get_event_forwarder_names() const
00226 {
00227     string_vector names;
00228     names.reserve(p_event_forwarder_base_map.size());
00229     event_forwarder_base_map::const_iterator it;
00230     for(it = p_event_forwarder_base_map.begin();
00231         it != p_event_forwarder_base_map.end();
00232         it++)
00233     { names.push_back(it->first); }
00234     return names;
00235 }
00236 
00237 void rc_abstract_interface_wrapper_b::notify_event(
00238     const std::string& event_name)
00239 {
00240     rc_event_forwarder_base& event_forwarder =
00241         this->_rc_get_event_forwarder(event_name);
00242     event_forwarder.trigger_event();
00243 }
00244 
00245 rc_event_forwarder_base&
00246 rc_abstract_interface_wrapper_b::_rc_get_event_forwarder(
00247     const std::string& event_name)
00248 {
00249     event_forwarder_base_map::iterator it =
00250         p_event_forwarder_base_map.find(event_name);
00251     if (it == p_event_forwarder_base_map.end()) {
00252         RC_REPORT_ERROR(RC_ID_DUPLICATE_ENTRY_,
00253             "event '" << event_name << "' does not exist"
00254             " (in interface wrapper '"
00255             << this->get_interface_wrapper_name() << "')");
00256     }
00257     return *(it->second);
00258 }
00259 
00260 void rc_abstract_interface_wrapper_b::_rc_spawn_event_forwarder_process(
00261     rc_event_forwarder_base& forwarder, const sc_event& e)
00262 {
00263     event_ef_map::iterator it = s_event_ef_map.find(&e);
00264     if (it == s_event_ef_map.end()) {
00265         event_ef_map_entry& new_map_entry_ = s_event_ef_map[&e];
00266         new_map_entry_.first = &forwarder;
00267 
00268         sc_spawn_options opt;
00269         {
00270             opt.spawn_method();
00271             opt.set_sensitivity(&e);
00272             opt.dont_initialize();
00273         }
00274         sc_spawn(
00275             sc_bind(
00276                 &rc_abstract_interface_wrapper_b::_rc_event_forwarder_proc,
00277                 sc_ref(new_map_entry_)),
00278             sc_gen_unique_name("_rc_event_forwarder_proc"), &opt);
00279     } else {
00280         event_ef_map_entry& map_entry_ = it->second;
00281         ef_vector& ef_vector_ = map_entry_.second;
00282         ef_vector_.push_back(&forwarder);
00283     }
00284 }
00285 
00286 void rc_abstract_interface_wrapper_b::_rc_event_forwarder_proc(
00287     event_ef_map_entry& map_entry_)
00288 {
00289     map_entry_.first->trigger_event();
00290     ef_vector& ef_vector_ = map_entry_.second;
00291     if (!ef_vector_.empty()) {
00292         for (ef_vector::iterator it = ef_vector_.begin();
00293             it != ef_vector_.end();
00294             ++it)
00295         {
00296             (*it)->trigger_event();
00297         }
00298     }
00299 }
00300 
00301 } // namespace ReChannel
00302 //
00303 // $Id: rc_abstract_interface_wrapper.cpp,v 1.12 2008/01/01 13:47:37 felke Exp $
00304 // $Source: /var/cvs/projekte/ReChannel-v2/src/ReChannel/communication/rc_abstract_interface_wrapper.cpp,v $
00305 //

Generated on Tue Jan 1 23:13:30 2008 for ReChannel by  doxygen 1.5.3