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