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 #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
00067 class sc_without_context;
00068 template <class T> class sc_global;
00069 template <class T> class sc_context;
00070
00071
00072
00073
00074
00075
00076
00077
00078 class sc_without_context {};
00079
00080
00081
00082
00083
00084
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
00114
00115
00116
00117
00118 enum sc_context_begin
00119 {
00120 SC_NOW,
00121 SC_LATER
00122 };
00123
00124
00125
00126
00127
00128
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
00157
00158
00159
00160
00161
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
00222
00223
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
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
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 }
00324
00325
00326 #endif
00327
00328