src/sysc/datatypes/fx/sc_context.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2005 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_context.h - 
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc.
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date:
00032   Description of Modification:
00033 
00034  *****************************************************************************/
00035 
00036 #ifndef SC_CONTEXT_H
00037 #define SC_CONTEXT_H
00038 
00039 
00040 #include "sysc/datatypes/fx/sc_fx_ids.h"
00041 #include "sysc/kernel/sc_simcontext.h"
00042 #include "sysc/utils/sc_hash.h"
00043 
00044 
00045 namespace sc_core {
00046         class sc_process_b;
00047 }
00048 
00049 
00050 namespace sc_dt
00051 {
00052 
00053 // classes defined in this module
00054 class sc_without_context;
00055 template <class T> class sc_global;
00056 template <class T> class sc_context;
00057 
00058 
00059 // ----------------------------------------------------------------------------
00060 //  CLASS : sc_without_context
00061 //
00062 //  Empty class that is used for its type only.
00063 // ----------------------------------------------------------------------------
00064 
00065 class sc_without_context {};
00066 
00067 
00068 // ----------------------------------------------------------------------------
00069 //  TEMPLATE CLASS : sc_global
00070 //
00071 //  Template global variable class; singleton; co-routine safe.
00072 // ----------------------------------------------------------------------------
00073 
00074 template <class T>
00075 class sc_global
00076 {
00077 
00078     sc_global();
00079 
00080     void update();
00081 
00082 public:
00083 
00084     static sc_global<T>* instance();
00085 
00086     const T*& value_ptr();
00087 
00088 private:
00089 
00090     static sc_global<T>* m_instance;
00091 
00092     sc_core::sc_phash<const sc_core::sc_process_b*,const T*> m_map;
00093     const sc_core::sc_process_b*                             m_proc;
00094     const T*                                                 m_value_ptr;
00095 
00096 };
00097 
00098 
00099 // ----------------------------------------------------------------------------
00100 //  ENUM : sc_context_begin
00101 //
00102 //  Enumeration of context begin options.
00103 // ----------------------------------------------------------------------------
00104 
00105 enum sc_context_begin
00106 {
00107     SC_NOW,
00108     SC_LATER
00109 };
00110 
00111 
00112 // ----------------------------------------------------------------------------
00113 //  CLASS : sc_context
00114 //
00115 //  Template context class; co-routine safe.
00116 // ----------------------------------------------------------------------------
00117 
00118 template <class T>
00119 class sc_context
00120 {
00121     sc_context( const sc_context<T>& );
00122     void* operator new( size_t );
00123 
00124 public:
00125 
00126     explicit sc_context( const T&, sc_context_begin = SC_NOW );
00127     ~sc_context();
00128 
00129     void begin();
00130     void end();
00131 
00132     static const T& default_value();
00133     const T& value() const;
00134 
00135 private:
00136 
00137     const T   m_value;
00138     const T*& m_def_value_ptr;
00139     const T*  m_old_value_ptr;
00140 };
00141 
00142 
00143 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00144 
00145 // ----------------------------------------------------------------------------
00146 //  TEMPLATE CLASS : sc_global
00147 //
00148 //  Template global variable class; singleton; co-routine safe.
00149 // ----------------------------------------------------------------------------
00150 
00151 template <class T>
00152 sc_global<T>* sc_global<T>::m_instance = 0;
00153 
00154 
00155 template <class T>
00156 inline
00157 sc_global<T>::sc_global()
00158 : m_proc( 
00159         reinterpret_cast<const sc_core::sc_process_b*>( -1 ) ), m_value_ptr( 0 )
00160 {}
00161 
00162 
00163 template <class T>
00164 inline
00165 void
00166 sc_global<T>::update()
00167 {
00168     const sc_core::sc_process_b* p = sc_core::sc_get_curr_process_handle();
00169     if( p != m_proc )
00170     {
00171         const T* vp = m_map[p];
00172         if( vp == 0 )
00173         {
00174             vp = new T( sc_without_context() );
00175             m_map.insert( p, vp );
00176         }
00177         m_proc = p;
00178         m_value_ptr = vp;
00179     }
00180 }
00181 
00182 
00183 template <class T>
00184 inline
00185 sc_global<T>*
00186 sc_global<T>::instance()
00187 {
00188     if( m_instance == 0 )
00189     {
00190         m_instance = new sc_global<T>;
00191     }
00192     return m_instance;
00193 }
00194 
00195 
00196 template <class T>
00197 inline
00198 const T*&
00199 sc_global<T>::value_ptr()
00200 {
00201     update();
00202     return m_value_ptr;
00203 }
00204 
00205 
00206 // ----------------------------------------------------------------------------
00207 //  CLASS : sc_context
00208 //
00209 //  Template context class; co-routine safe.
00210 // ----------------------------------------------------------------------------
00211 
00212 template <class T>
00213 inline
00214 sc_context<T>::sc_context( const sc_context<T>& )
00215 : m_value(),
00216   m_def_value_ptr( sc_global<T>::instance()->value_ptr() ),
00217   m_old_value_ptr( 0 )
00218 {
00219     // this constructor should never be called
00220     SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_, "should never be called" );
00221 }
00222 
00223 template <class T>
00224 inline
00225 void*
00226 sc_context<T>::operator new( size_t )
00227 {
00228     // this method should never be called
00229     SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_, "should never be called" );
00230 }
00231 
00232 
00233 template <class T>
00234 inline
00235 sc_context<T>::sc_context( const T& value_, sc_context_begin begin )
00236 : m_value( value_ ),
00237   m_def_value_ptr( sc_global<T>::instance()->value_ptr() ),
00238   m_old_value_ptr( 0 )
00239 {
00240     if( begin == SC_NOW )
00241     {
00242         m_old_value_ptr = m_def_value_ptr;
00243         m_def_value_ptr = &m_value;
00244     }
00245 }
00246 
00247 template <class T>
00248 inline
00249 sc_context<T>::~sc_context()
00250 {
00251     if( m_old_value_ptr != 0 )
00252     {
00253         m_def_value_ptr = m_old_value_ptr;
00254         m_old_value_ptr = 0;
00255     }
00256 }
00257 
00258 
00259 template <class T>
00260 inline
00261 void
00262 sc_context<T>::begin()
00263 {
00264     if( m_old_value_ptr == 0 )
00265     {
00266         m_old_value_ptr = m_def_value_ptr;
00267         m_def_value_ptr = &m_value;
00268     }
00269     else
00270     {
00271         SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0 );
00272     }
00273 }
00274 
00275 template <class T>
00276 inline
00277 void
00278 sc_context<T>::end()
00279 {
00280     if( m_old_value_ptr != 0 )
00281     {
00282         m_def_value_ptr = m_old_value_ptr;
00283         m_old_value_ptr = 0;
00284     }
00285     else
00286     {
00287         SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_END_FAILED_, 0 );
00288     }
00289 }
00290 
00291 
00292 template <class T>
00293 inline
00294 const T&
00295 sc_context<T>::default_value()
00296 {
00297     return *sc_global<T>::instance()->value_ptr();
00298 }
00299 
00300 template <class T>
00301 inline
00302 const T&
00303 sc_context<T>::value() const
00304 {
00305     return m_value;
00306 }
00307 
00308 } // namespace sc_dt
00309 
00310 
00311 #endif
00312 
00313 // Taf!

Generated on Wed Apr 25 13:53:26 2007 for SystemC by  doxygen 1.5.1