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 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 #ifndef SC_CONTEXT_H
00057 #define SC_CONTEXT_H
00058 
00059 
00060 #include "sysc/datatypes/fx/sc_fx_ids.h"
00061 #include "sysc/kernel/sc_simcontext.h"
00062 #include "sysc/utils/sc_hash.h"
00063 
00064 
00065 namespace sc_core {
00066         class sc_process_b;
00067 }
00068 
00069 using sc_core::default_ptr_hash_fn; 
00070 
00071 namespace sc_dt
00072 {
00073 
00074 
00075 class sc_without_context;
00076 template <class T> class sc_global;
00077 template <class T> class sc_context;
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 class sc_without_context {};
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 template <class T>
00096 class sc_global
00097 {
00098 
00099     sc_global();
00100 
00101     void update();
00102 
00103 public:
00104 
00105     static sc_global<T>* instance();
00106 
00107     const T*& value_ptr();
00108 
00109 private:
00110     static sc_global<T>* m_instance;
00111 
00112     sc_core::sc_phash<void*,const T*> m_map;
00113     void*                             m_proc; 
00114     const T*                          m_value_ptr;
00115 
00116 };
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 enum sc_context_begin
00126 {
00127     SC_NOW,
00128     SC_LATER
00129 };
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 template <class T>
00139 class sc_context
00140 {
00141     
00142     sc_context( const sc_context<T>& );
00143     void* operator new( std::size_t );
00144 
00145 public:
00146 
00147     explicit sc_context( const T&, sc_context_begin = SC_NOW );
00148     ~sc_context();
00149 
00150     void begin();
00151     void end();
00152 
00153     static const T& default_value();
00154     const T& value() const;
00155 
00156 private:
00157 
00158     const T   m_value;
00159     const T*& m_def_value_ptr;
00160     const T*  m_old_value_ptr;
00161 };
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 template <class T>
00173 sc_global<T>* sc_global<T>::m_instance = 0;
00174 
00175 template <class T>
00176 inline
00177 sc_global<T>::sc_global()
00178   : m_map()
00179   
00180   , m_proc( &m_instance )
00181   , m_value_ptr( 0 )
00182 {}
00183 
00184 
00185 template <class T>
00186 inline
00187 void
00188 sc_global<T>::update()
00189 {
00190     void* p = sc_core::sc_get_current_process_b();
00191     if( p != m_proc )
00192     {
00193         const T* vp = m_map[p];
00194         if( vp == 0 )
00195         {
00196             vp = new T( sc_without_context() );
00197             m_map.insert( p, vp );
00198         }
00199         m_proc = p;
00200         m_value_ptr = vp;
00201     }
00202 }
00203 
00204 
00205 template <class T>
00206 inline
00207 sc_global<T>*
00208 sc_global<T>::instance()
00209 {
00210     if( m_instance == 0 )
00211     {
00212         m_instance = new sc_global<T>;
00213     }
00214     return m_instance;
00215 }
00216 
00217 
00218 template <class T>
00219 inline
00220 const T*&
00221 sc_global<T>::value_ptr()
00222 {
00223     update();
00224     return m_value_ptr;
00225 }
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 template <class T>
00235 inline
00236 sc_context<T>::sc_context( const T& value_, sc_context_begin begin )
00237 : m_value( value_ ),
00238   m_def_value_ptr( sc_global<T>::instance()->value_ptr() ),
00239   m_old_value_ptr( 0 )
00240 {
00241     if( begin == SC_NOW )
00242     {
00243         m_old_value_ptr = m_def_value_ptr;
00244         m_def_value_ptr = &m_value;
00245     }
00246 }
00247 
00248 template <class T>
00249 inline
00250 sc_context<T>::~sc_context()
00251 {
00252     if( m_old_value_ptr != 0 )
00253     {
00254         m_def_value_ptr = m_old_value_ptr;
00255         m_old_value_ptr = 0;
00256     }
00257 }
00258 
00259 
00260 template <class T>
00261 inline
00262 void
00263 sc_context<T>::begin()
00264 {
00265     if( m_old_value_ptr == 0 )
00266     {
00267         m_old_value_ptr = m_def_value_ptr;
00268         m_def_value_ptr = &m_value;
00269     }
00270     else
00271     {
00272         SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0 );
00273     }
00274 }
00275 
00276 template <class T>
00277 inline
00278 void
00279 sc_context<T>::end()
00280 {
00281     if( m_old_value_ptr != 0 )
00282     {
00283         m_def_value_ptr = m_old_value_ptr;
00284         m_old_value_ptr = 0;
00285     }
00286     else
00287     {
00288         SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_END_FAILED_, 0 );
00289     }
00290 }
00291 
00292 
00293 template <class T>
00294 inline
00295 const T&
00296 sc_context<T>::default_value()
00297 {
00298     return *sc_global<T>::instance()->value_ptr();
00299 }
00300 
00301 template <class T>
00302 inline
00303 const T&
00304 sc_context<T>::value() const
00305 {
00306     return m_value;
00307 }
00308 
00309 } 
00310 
00311 
00312 #endif
00313 
00314