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 #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
00054 class sc_without_context;
00055 template <class T> class sc_global;
00056 template <class T> class sc_context;
00057
00058
00059
00060
00061
00062
00063
00064
00065 class sc_without_context {};
00066
00067
00068
00069
00070
00071
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
00101
00102
00103
00104
00105 enum sc_context_begin
00106 {
00107 SC_NOW,
00108 SC_LATER
00109 };
00110
00111
00112
00113
00114
00115
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
00144
00145
00146
00147
00148
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
00208
00209
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
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
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 }
00309
00310
00311 #endif
00312
00313