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-2006 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 // $Log: sc_context.h,v $
00037 // Revision 1.1.1.1  2006/12/15 20:31:36  acg
00038 // SystemC 2.2
00039 //
00040 // Revision 1.4  2006/03/21 00:00:31  acg
00041 //   Andy Goodrich: changed name of sc_get_current_process_base() to be
00042 //   sc_get_current_process_b() since its returning an sc_process_b instance.
00043 //
00044 // Revision 1.3  2006/01/13 18:53:57  acg
00045 // Andy Goodrich: added $Log command so that CVS comments are reproduced in
00046 // the source.
00047 //
00048 
00049 #ifndef SC_CONTEXT_H
00050 #define SC_CONTEXT_H
00051 
00052 
00053 #include "sysc/datatypes/fx/sc_fx_ids.h"
00054 #include "sysc/kernel/sc_simcontext.h"
00055 #include "sysc/utils/sc_hash.h"
00056 
00057 namespace sc_core {
00058     class sc_process_b;
00059 }
00060 
00061 using sc_core::default_ptr_hash_fn;
00062 
00063 namespace sc_dt
00064 {
00065 
00066 // classes defined in this module
00067 class sc_without_context;
00068 template <class T> class sc_global;
00069 template <class T> class sc_context;
00070 
00071 
00072 // ----------------------------------------------------------------------------
00073 //  CLASS : sc_without_context
00074 //
00075 //  Empty class that is used for its type only.
00076 // ----------------------------------------------------------------------------
00077 
00078 class sc_without_context {};
00079 
00080 
00081 // ----------------------------------------------------------------------------
00082 //  TEMPLATE CLASS : sc_global
00083 //
00084 //  Template global variable class; singleton; co-routine safe.
00085 // ----------------------------------------------------------------------------
00086 
00087 template <class T>
00088 class sc_global
00089 {
00090 
00091     sc_global();
00092 
00093     void update();
00094 
00095 public:
00096 
00097     static sc_global<T>* instance();
00098 
00099     const T*& value_ptr();
00100 
00101 private:
00102 
00103     static sc_global<T>* m_instance;
00104 
00105     sc_core::sc_phash<const sc_core::sc_process_b*,const T*> m_map;
00106     const sc_core::sc_process_b*                             m_proc;
00107     const T*                                                    m_value_ptr;
00108 
00109 };
00110 
00111 
00112 // ----------------------------------------------------------------------------
00113 //  ENUM : sc_context_begin
00114 //
00115 //  Enumeration of context begin options.
00116 // ----------------------------------------------------------------------------
00117 
00118 enum sc_context_begin
00119 {
00120     SC_NOW,
00121     SC_LATER
00122 };
00123 
00124 
00125 // ----------------------------------------------------------------------------
00126 //  CLASS : sc_context
00127 //
00128 //  Template context class; co-routine safe.
00129 // ----------------------------------------------------------------------------
00130 
00131 template <class T>
00132 class sc_context
00133 {
00134     sc_context( const sc_context<T>& );
00135     void* operator new( std::size_t );
00136 
00137 public:
00138 
00139     explicit sc_context( const T&, sc_context_begin = SC_NOW );
00140     ~sc_context();
00141 
00142     void begin();
00143     void end();
00144 
00145     static const T& default_value();
00146     const T& value() const;
00147 
00148 private:
00149 
00150     const T   m_value;
00151     const T*& m_def_value_ptr;
00152     const T*  m_old_value_ptr;
00153 };
00154 
00155 
00156 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
00157 
00158 // ----------------------------------------------------------------------------
00159 //  TEMPLATE CLASS : sc_global
00160 //
00161 //  Template global variable class; singleton; co-routine safe.
00162 // ----------------------------------------------------------------------------
00163 
00164 template <class T>
00165 sc_global<T>* sc_global<T>::m_instance = 0;
00166 
00167 
00168 template <class T>
00169 inline
00170 sc_global<T>::sc_global()
00171 : m_proc( 
00172     reinterpret_cast<const sc_core::sc_process_b*>( -1 ) ), 
00173     m_value_ptr( 0 )
00174 {}
00175 
00176 
00177 template <class T>
00178 inline
00179 void
00180 sc_global<T>::update()
00181 {
00182     const sc_core::sc_process_b* p = sc_core::sc_get_current_process_b();
00183     if( p != m_proc )
00184     {
00185         const T* vp = m_map[p];
00186         if( vp == 0 )
00187         {
00188             vp = new T( sc_without_context() );
00189             m_map.insert( p, vp );
00190         }
00191         m_proc = p;
00192         m_value_ptr = vp;
00193     }
00194 }
00195 
00196 
00197 template <class T>
00198 inline
00199 sc_global<T>*
00200 sc_global<T>::instance()
00201 {
00202     if( m_instance == 0 )
00203     {
00204         m_instance = new sc_global<T>;
00205     }
00206     return m_instance;
00207 }
00208 
00209 
00210 template <class T>
00211 inline
00212 const T*&
00213 sc_global<T>::value_ptr()
00214 {
00215     update();
00216     return m_value_ptr;
00217 }
00218 
00219 
00220 // ----------------------------------------------------------------------------
00221 //  CLASS : sc_context
00222 //
00223 //  Template context class; co-routine safe.
00224 // ----------------------------------------------------------------------------
00225 
00226 template <class T>
00227 inline
00228 sc_context<T>::sc_context( const sc_context<T>& )
00229 : m_value(),
00230   m_def_value_ptr( sc_global<T>::instance()->value_ptr() ),
00231   m_old_value_ptr( 0 )
00232 {
00233     // this constructor should never be called
00234     SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_, "should never be called" );
00235 }
00236 
00237 template <class T>
00238 inline
00239 void*
00240 sc_context<T>::operator new( std::size_t )
00241 {
00242     // this method should never be called
00243     SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_, "should never be called" );
00244     return (void*)0;
00245 }
00246 
00247 
00248 template <class T>
00249 inline
00250 sc_context<T>::sc_context( const T& value_, sc_context_begin begin )
00251 : m_value( value_ ),
00252   m_def_value_ptr( sc_global<T>::instance()->value_ptr() ),
00253   m_old_value_ptr( 0 )
00254 {
00255     if( begin == SC_NOW )
00256     {
00257     m_old_value_ptr = m_def_value_ptr;
00258     m_def_value_ptr = &m_value;
00259     }
00260 }
00261 
00262 template <class T>
00263 inline
00264 sc_context<T>::~sc_context()
00265 {
00266     if( m_old_value_ptr != 0 )
00267     {
00268         m_def_value_ptr = m_old_value_ptr;
00269     m_old_value_ptr = 0;
00270     }
00271 }
00272 
00273 
00274 template <class T>
00275 inline
00276 void
00277 sc_context<T>::begin()
00278 {
00279     if( m_old_value_ptr == 0 )
00280     {
00281     m_old_value_ptr = m_def_value_ptr;
00282     m_def_value_ptr = &m_value;
00283     }
00284     else
00285     {
00286         SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0 );
00287     }
00288 }
00289 
00290 template <class T>
00291 inline
00292 void
00293 sc_context<T>::end()
00294 {
00295     if( m_old_value_ptr != 0 )
00296     {
00297         m_def_value_ptr = m_old_value_ptr;
00298     m_old_value_ptr = 0;
00299     }
00300     else
00301     {
00302         SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_END_FAILED_, 0 );
00303     }
00304 }
00305 
00306 
00307 template <class T>
00308 inline
00309 const T&
00310 sc_context<T>::default_value()
00311 {
00312     return *sc_global<T>::instance()->value_ptr();
00313 }
00314 
00315 template <class T>
00316 inline
00317 const T&
00318 sc_context<T>::value() const
00319 {
00320     return m_value;
00321 }
00322 
00323 } // namespace sc_dt
00324 
00325 
00326 #endif
00327 
00328 // Taf!

Generated on Wed Jan 21 15:32:07 2009 for SystemC by  doxygen 1.5.5