rc_reconfigurable.h

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 #ifndef RC_RECONFIGURABLE_H_
00038 #define RC_RECONFIGURABLE_H_
00039 
00040 #include <boost/multi_index_container.hpp>
00041 #include <boost/multi_index/ordered_index.hpp>
00042 #include <boost/multi_index/member.hpp>
00043 
00044 #include "ReChannel/core/rc_common_header.h"
00045 #include "ReChannel/core/rc_switch.h"
00046 #include "ReChannel/core/rc_resettable.h"
00047 #include "ReChannel/core/rc_process.h"
00048 #include "ReChannel/core/rc_reconfigurable_set.h"
00049 #include "ReChannel/core/rc_portmap.h"
00050 #include "ReChannel/core/rc_switch_connector.h"
00051 
00052 #include "ReChannel/util/rc_driver_object.h"
00053 #include "ReChannel/util/rc_mutex_object.h"
00054 #include "ReChannel/util/rc_delta_sync_object.h"
00055 #include "ReChannel/util/rc_hash_map.h"
00056 #include "ReChannel/util/rc_object_handle.h"
00057 #include "ReChannel/util/rc_port_handle.h"
00058 #include "ReChannel/util/rc_export_handle.h"
00059 
00060 namespace ReChannel {
00061 
00062 class rc_control;
00063 class rc_transaction_counter;
00064 
00065 // forward declarations
00066 class rc_reconfigurable;
00067 rc_reconfigurable* rc_get_reconfigurable_context();
00068 rc_reconfigurable* rc_get_reconfigurable_context(sc_object* start_search);
00069 
00070 namespace internals {
00071 namespace reconfigurable {
00072 
00081 class temporary_object : public sc_object {};
00082 
00100 class begin_construction
00101 {
00102     friend void end_construction(begin_construction& constr);
00103     friend rc_reconfigurable* ::ReChannel::rc_get_reconfigurable_context();
00104     friend rc_reconfigurable* ::ReChannel::rc_get_reconfigurable_context(
00105         sc_object* start_search);
00106 
00107 protected:
00114     explicit begin_construction(rc_reconfigurable& reconf);
00115 
00124     void finish();
00125 
00136     void finish(sc_object& reconf);
00137 
00143     ~begin_construction()
00144         { finish(); }
00145 
00146 private:
00151     rc_reconfigurable* p_previous;
00155     bool               p_finished;
00156 
00157 private:
00162     static rc_reconfigurable* s_current;
00163 
00164 private:
00165     //disabled
00167     begin_construction(const begin_construction& reconf);
00169     begin_construction& operator=(const begin_construction& reconf);
00170 };
00171 
00181 inline void end_construction(begin_construction& constr)
00182     { constr.finish(); }
00183 
00184 } // namespace reconfigurable
00185 } // namespace internals
00186 
00207 class rc_reconfigurable
00208 {
00212     friend class rc_control;
00213 
00214     friend class internals::reconfigurable::begin_construction;
00215 
00219     friend class rc_transaction;
00220 
00225     friend class rc_transaction_counter;
00226 
00227 public:
00232     typedef rc_switch_connector_base switch_conn_type;
00233 
00238     typedef rc_switch::filter_chain  filter_chain;
00239 
00240 private:
00241     typedef std::pair<rc_switch*, rc_object_handle> switch_commobj_pair;
00242 
00247     typedef boost::multi_index_container<
00248               switch_commobj_pair,
00249               boost::multi_index::indexed_by<
00250                 boost::multi_index::ordered_unique<
00251                   BOOST_MULTI_INDEX_MEMBER(
00252                     switch_commobj_pair, rc_switch*, first)
00253                 >,
00254                 boost::multi_index::ordered_non_unique<
00255                   BOOST_MULTI_INDEX_MEMBER(
00256                     switch_commobj_pair, rc_object_handle, second)
00257                 >
00258               >
00259             > switch_commobj_map;
00260 
00264     typedef switch_commobj_map::nth_index<0>::type   switch_commobj_index;
00265 
00269     typedef switch_commobj_map::nth_index<1>::type   commobj_switch_index;
00270 
00274     typedef std::pair<
00275                 switch_commobj_index::iterator,
00276                 switch_commobj_index::iterator>      switch_commobj_range;
00277 
00281     typedef std::pair<
00282                 commobj_switch_index::iterator,
00283                 commobj_switch_index::iterator>      commobj_switch_range;
00284 
00288     typedef std::set<rc_interface_filter*>           filter_set;
00289 
00293     typedef std::map<rc_object_handle, filter_chain> commobj_filters_map;
00294 
00298     typedef std::set<rc_resettable*>                 resettable_set;
00299 
00303     typedef std::vector<rc_portmap_base*>            portmap_vector;
00304 
00305 public:
00309     enum state_type { UNLOADED=0, INACTIVE, ACTIVE };
00310 
00314     enum { STATE_COUNT=3 };
00315 
00319     enum action_type { UNLOAD=0, LOAD, ACTIVATE, DEACTIVATE };
00320 
00324     enum { ACTION_COUNT=4 };
00325 
00326 protected:
00327 
00333     rc_reconfigurable(sc_object* this_=NULL);
00334 
00335 public:
00336 
00343     std::string rc_get_name() const;
00344 
00350     const sc_object* rc_get_object() const;
00351 
00357     sc_object* rc_get_object();
00358 
00362     inline state_type rc_get_state() const
00363         { return p_state; }
00364 
00369     inline bool rc_is_state_changing() const
00370         { return (p_state != p_next_state); }
00371 
00375     inline state_type rc_get_next_state() const
00376         { return p_next_state; }
00377 
00381     inline bool rc_is_loaded() const
00382         { return (p_state != UNLOADED); }
00383 
00387     inline bool rc_is_active() const
00388         { return (p_state == ACTIVE); }
00389 
00396     inline int rc_get_transaction_count() const
00397         { return p_transaction_count; }
00398 
00404     void bind(rc_switch_connector_base& switch_connector);
00405 
00414     void rc_register_switch(
00415         rc_switch& switch_obj, const rc_object_handle& bound_obj);
00416 
00420     bool rc_is_registered(rc_switch& switch_obj) const;
00421 
00430     void rc_register_resettable(rc_resettable& resettable);
00431 
00435     bool rc_is_registered(rc_resettable& resettable) const;
00436 
00446     inline void rc_begin_transaction()
00447         { ++p_transaction_count; }
00448 
00458     inline void rc_end_transaction();
00459 
00467     void rc_possible_deactivation();
00468 
00480     void rc_possible_deactivation_delta();
00481 
00485     inline bool rc_is_deactivation_requested() const
00486         { return (p_next_state == INACTIVE && p_state == ACTIVE); }
00487 
00494     void rc_set_delay(action_type a, sc_time t);
00495 
00499     inline sc_time rc_get_delay(action_type a) const
00500         { return p_action_delays[a]; }
00501 
00505     inline void rc_set_default_delay(action_type a, sc_time t)
00506         { p_action_default_delays[a] = t; }
00507 
00516     inline sc_time rc_get_default_delay(action_type a) const
00517         { return p_action_default_delays[a]; }
00518 
00524     inline operator const rc_reconfigurable_set&() const
00525         { return p_self_set; }
00526 
00535     inline const rc_process_control& rc_get_process_control() const
00536         { return p_pctrl; }
00537 
00544     inline switch_conn_type* rc_get_current_switch_connector() const
00545         { return p_curr_switch_conn; }
00546 
00550     virtual ~rc_reconfigurable();
00551 
00552 protected:
00553 
00562     virtual void rc_on_load() {}
00563 
00572     virtual void rc_on_activate() {}
00573 
00582     virtual void rc_on_deactivate() {}
00583 
00592     virtual void rc_on_unload() {}
00593 
00602     void rc_add_portmap(rc_portmap_base& portmap);
00603 
00607     void rc_clear_portmaps();
00608 
00614     bool rc_is_compatible(const rc_portmap_base& portmap) const
00615         { return (this->_rc_is_compatible(portmap) > -1); }
00616 
00623     void rc_add_filter(
00624         const rc_object_handle& commobj_, rc_interface_filter& filter_);
00625 
00630     int rc_get_filter_count(const rc_object_handle& commobj_) const;
00631 
00636     filter_chain rc_get_filter_chain(
00637         const rc_object_handle& commobj_) const;
00638 
00642     bool rc_has_filter(rc_interface_filter& filter_) const;
00643 
00648     void rc_refresh_notify(const rc_object_handle& commobj_);
00649 
00654     void rc_refresh_notify_all();
00655 
00656 private:
00657 
00662     static void get_all_reconfigurables(
00663         std::vector<rc_reconfigurable*>& copy_dest)
00664         { copy_dest = s_reconfigurables; }
00665 
00666 private:
00670     inline rc_control* get_control() const
00671         { return p_control; }
00672 
00676     void set_control(rc_control* control)
00677         { p_control = control; }
00678 
00688     void start_of_simulation();
00689 
00695     void reconfigure(state_type new_state);
00696 
00701     void change_switch_state(rc_switch::state_type new_state);
00702 
00707     void move(switch_conn_type& target);
00708 
00712     inline bool has_lock() const
00713         { return p_mutex.has_lock(); }
00714 
00718     inline bool is_locked() const
00719         { return p_mutex.is_locked(); }
00720 
00724     inline const sc_event& get_lock_release_event() const
00725         { return p_mutex.get_lock_release_event(); }
00726 
00731     inline bool trylock()
00732         { return p_mutex.trylock(); }
00733 
00737     inline void lock()
00738         { p_mutex.lock(); }
00739 
00743     inline bool lock(sc_time timeout)
00744         { return p_mutex.lock(timeout); }
00745 
00750     bool unlock();
00751 
00758     bool share_lock(sc_process_handle proc);
00759 
00763     bool reset_lock_share();
00764 
00768     inline bool has_lock_share() const
00769         { return (p_lock_share == sc_get_current_process_handle()); }
00770 
00775     bool lock_switches(bool report_error=false);
00776 
00782     void unlock_switches();
00783 
00789     void reset_transaction_count();
00790 
00794     rc_portmap_base& get_portmap(int index);
00795 
00799     int get_portmap_count() const
00800         { return p_portmap_vector.size(); }
00801 
00802 private:
00803 
00804 /* for internal use only */
00805 
00809     void _rc_set_sc_object(sc_object& reconf);
00810 
00817     void _rc_delta_sync_state_change(rc_delta_sync_object& delta_sync);
00818 
00822     void _rc_unload();
00823 
00827     void _rc_load();
00828 
00832     void _rc_activate();
00833 
00837     void _rc_deactivate();
00838 
00842     void _rc_reset();
00843 
00847     int _rc_is_compatible(const rc_portmap_base& portmap) const;
00848 
00852     rc_portmap_base* _rc_get_compatible_portmap(
00853         const rc_switch_connector_base& switch_conn) const;
00854 
00855 private:
00859     static std::vector<rc_reconfigurable*> s_reconfigurables;
00860 
00861 private:
00867     mutable sc_object*    p_sc_object;
00871     mutable bool          p_is_no_sc_object;
00872 
00876     state_type            p_state;
00883     state_type            p_next_state;
00889     int                   p_transaction_count;
00890 
00897     rc_process_control    p_pctrl;
00901     rc_delta_sync_object  p_delta_sync;
00902 
00903     switch_commobj_map    p_switch_commobj_map;
00904     switch_commobj_index& p_switch_commobj_index;
00905     commobj_switch_index& p_commobj_switch_index;
00906 
00907     filter_set            p_filter_set;
00908     commobj_filters_map   p_commobj_filters_map;
00909 
00910     rc_control*           p_control;
00911     rc_reconfigurable_set p_self_set;
00912     rc_mutex_object       p_mutex;
00913     sc_process_handle     p_lock_share;
00914     sc_time               p_action_default_delays[ACTION_COUNT];
00915     sc_time               p_action_delays[ACTION_COUNT];
00916 
00917     portmap_vector        p_portmap_vector;
00918     switch_conn_type*     p_curr_switch_conn;
00919 
00920     resettable_set        p_resettable_set;
00921 };
00922 
00941 class rc_transaction
00942 {
00943 public:
00948     inline explicit rc_transaction(rc_reconfigurable* reconf);
00953     inline void begin();
00959     inline void end();
00963     inline bool has_ended() const
00964         { return p_has_ended; }
00968     ~rc_transaction();
00969 private:
00970     // disabled
00972     rc_transaction(const rc_transaction& orig);
00974     rc_transaction& operator=(const rc_transaction& orig);
00975 private:
00979     rc_reconfigurable* reconf;
00983     bool p_has_ended;
00984 };
00985 
00986 /* inline code */
00987 
00988 inline void rc_reconfigurable::rc_end_transaction()
00989 {
00990     if (p_transaction_count > 1) {
00991         --p_transaction_count;
00992     } else {
00993         this->reset_transaction_count();
00994     }
00995 }
00996 
00997 inline rc_transaction::rc_transaction(rc_reconfigurable* reconf)
00998     : reconf(reconf), p_has_ended(false)
00999 {
01000     if (reconf != NULL) {
01001         reconf->rc_begin_transaction();
01002     }
01003     // p_has_ended must initially be set to false (see RC_TRANSACTION)
01004 }
01005 
01006 inline void rc_transaction::begin()
01007 {
01008     if (p_has_ended && reconf != NULL) {
01009         reconf->rc_begin_transaction();
01010     }
01011     // this must always be set, to allow RC_TRANSACTION to work properly
01012     p_has_ended = false;
01013 }
01014 
01015 inline void rc_transaction::end()
01016 {
01017     if (!p_has_ended && reconf != NULL) {
01018         reconf->rc_end_transaction();
01019         reconf->rc_possible_deactivation();
01020     }
01021     // this must always be set, to allow RC_TRANSACTION to work properly
01022     p_has_ended = true;
01023 }
01024 
01025 /* global functions */
01026 
01042 extern rc_reconfigurable* rc_get_reconfigurable_context();
01043 
01060 extern rc_reconfigurable* rc_get_reconfigurable_context(
01061     sc_object* start_search);
01062 
01071 extern const rc_reconfigurable* rc_register_resettable(
01072     rc_resettable& resettable, sc_object* search_start);
01073 
01074 } // namespace ReChannel
01075 
01080 #define RC_LOAD       rc_reconfigurable::LOAD
01081 
01085 #define RC_ACTIVATE   rc_reconfigurable::ACTIVATE
01086 
01090 #define RC_DEACTIVATE rc_reconfigurable::DEACTIVATE
01091 
01095 #define RC_UNLOAD     rc_reconfigurable::UNLOAD
01096 
01101 #define RC_ACTIVE   rc_reconfigurable::ACTIVE
01102 
01106 #define RC_INACTIVE rc_reconfigurable::INACTIVE
01107 
01111 #define RC_UNLOADED rc_reconfigurable::UNLOADED
01112 
01129 #define RC_ON_LOAD() \
01130         virtual void rc_on_load()
01131 
01147 #define RC_ON_ACTIVATE() \
01148         virtual void rc_on_activate()
01149 
01165 #define RC_ON_DEACTIVATE() \
01166         virtual void rc_on_deactivate()
01167 
01183 #define RC_ON_UNLOAD() \
01184         virtual void rc_on_unload()
01185 
01186 #endif //RC_RECONFIGURABLE_H_
01187 
01188 //
01189 // $Id: rc_reconfigurable.h,v 1.22 2008/01/01 13:34:00 felke Exp $
01190 // $Source: /var/cvs/projekte/ReChannel-v2/src/ReChannel/core/rc_reconfigurable.h,v $
01191 //

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