Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

scv_tr.cpp

Go to the documentation of this file.
00001 //  -*- C++ -*- <this line is for emacs to recognize it as C++ code>
00002 /*****************************************************************************
00003 
00004   The following code is derived, directly or indirectly, from the SystemC
00005   source code Copyright (c) 1996-2002 by all Contributors.
00006   All Rights reserved.
00007 
00008   The contents of this file are subject to the restrictions and limitations
00009   set forth in the SystemC Open Source License Version 2.3 (the "License");
00010   You may not use this file except in compliance with such restrictions and
00011   limitations. You may obtain instructions on how to receive a copy of the
00012   License at http://www.systemc.org/. Software distributed by Contributors
00013   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00014   ANY KIND, either express or implied. See the License for the specific
00015   language governing rights and limitations under the License.
00016 
00017  *****************************************************************************/
00018 
00019 /*****************************************************************************
00020 
00021   scv_tr.cpp -- The implementation of the transaction recording facility in
00022   scv_tr.h
00023 
00024   Original Authors (Cadence Design Systems, Inc):
00025   Norris Ip, Dean Shea, John Rose, Jasvinder Singh, William Paulsen,
00026   John Pierce, Rachida Kebichi, Ted Elkind, David Bailey
00027   2002-09-23
00028 
00029  *****************************************************************************/
00030 
00031 /*****************************************************************************
00032 
00033   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00034   changes you are making here.
00035 
00036       Name, Affiliation, Date:
00037   Description of Modification:
00038 
00039  *****************************************************************************/
00040 
00041 #include <list>
00042 #include <map>
00043 #include <string>
00044 
00045 #include "scv.h"
00046 #include "scv/scv_config.h"
00047 #include "scv/scv_debug.h"
00048 #include "scv/scv_introspection.h"
00049 #include "scv/scv_tr.h"
00050 
00051 // ----------------------------------------------------------------------------
00052 
00053 //#define scv_tr_TRACE
00054 
00055 // ----------------------------------------------------------------------------
00056 
00057 static void scv_tr_null_scv_tr_db_message()
00058 {
00059   static bool message_given = false;
00060 
00061   if (message_given == false) {
00062     message_given = true;
00063 
00064    _scv_message::message(
00065                 _scv_message::TRANSACTION_RECORDING_INTERNAL,
00066                 "The scv_tr_db argument to a scv_tr method is NULL");
00067   }
00068 }
00069 
00070 // ----------------------------------------------------------------------------
00071 
00072 typedef void _scv_tr_void_function_t();
00073 
00074 class _scv_tr_callback_item_t {
00075  public:
00076 
00077   _scv_tr_callback_item_t()
00078   {
00079     id_counter++;
00080     this->id = id_counter;
00081   };
00082 
00083   static int id_counter;
00084   int id;
00085   void* callback_fp;
00086   void* user_data_p;
00087 };
00088 
00089 int _scv_tr_callback_item_t::id_counter = 0;
00090 
00091 typedef list<_scv_tr_callback_item_t*> _scv_tr_callback_list;
00092 
00093 // ----------------------------------------------------------------------------
00094 
00095 static char* scv_tr_strdup(const char* src_str)
00096 {
00097   if (src_str) return strdup(src_str);
00098   else return NULL;
00099 }
00100 
00101 // ----------------------------------------------------------------------------
00102 
00103 class _scv_tr_db_core {
00104  public:
00105 
00106   _scv_tr_db_core(
00107   const char* recording_file_name,
00108   const sc_time_unit& _time_unit);
00109 
00110   ~_scv_tr_db_core() {};
00111 
00112   static scv_tr_db* default_scv_tr_db_p;
00113   scv_tr_db* my_scv_tr_db_p;
00114   sc_time_unit my_sc_time_unit;
00115   string my_name;
00116   bool state;
00117   static int debug;
00118 
00119   uint64 global_id;  // Global counter of objects in this scv_tr_db
00120   uint64 global_transaction_id;
00121 
00122   // A list of callbacks registered for this class:
00123   //
00124   static _scv_tr_callback_list* callback_list_p;
00125 
00126   // A map of relation string names, by handle:
00127   //
00128   scv_tr_relation_handle_t relation_handle_counter;
00129   map<scv_tr_relation_handle_t, string> relation_by_handle_map;
00130   map<string, scv_tr_relation_handle_t> relation_by_name_map;
00131 };
00132 
00133 int _scv_tr_db_core::debug = -1;
00134 scv_tr_db* _scv_tr_db_core::default_scv_tr_db_p = NULL;
00135 _scv_tr_callback_list* _scv_tr_db_core::callback_list_p = NULL;
00136 
00137 // ----------------------------------------------------------------------------
00138 
00139 _scv_tr_db_core::_scv_tr_db_core(
00140         const char* recording_file_name,
00141         const sc_time_unit& _time_unit)
00142 {
00143   this->my_name = scv_tr_strdup(recording_file_name);
00144   this->state = true;
00145   this->my_sc_time_unit = _time_unit;
00146   this->global_id = 1;
00147   this->global_transaction_id = 1;
00148   this->relation_handle_counter = 0;
00149 };
00150 
00151 // ----------------------------------------------------------------------------
00152 
00153 class _scv_tr_stream_core {
00154   friend class scv_tr_stream;
00155  public:
00156   scv_tr_stream* my_scv_tr_stream_p;
00157   char* my_name;
00158   char* my_stream_kind_name;
00159   _scv_tr_db_core* my_scv_tr_db_core_p;
00160   static int debug;
00161 
00162   uint64 my_id;
00163 
00164   static _scv_tr_callback_list* callback_list_p;
00165 
00166   _scv_tr_stream_core(
00167     _scv_tr_db_core* _scv_tr_db_core_p,
00168     scv_tr_stream* scv_tr_stream_p,
00169     const char* name,
00170                 const char* _stream_kind_name)
00171   {
00172     this->my_scv_tr_db_core_p = _scv_tr_db_core_p;
00173     this->my_scv_tr_stream_p = scv_tr_stream_p;
00174     this->my_name = scv_tr_strdup(name);
00175     this->my_stream_kind_name = scv_tr_strdup(_stream_kind_name);
00176     this->my_id = this->my_scv_tr_db_core_p->global_id++;
00177   };
00178 
00179 };
00180 
00181 int _scv_tr_stream_core::debug = -1;
00182 _scv_tr_callback_list* _scv_tr_stream_core::callback_list_p = NULL;
00183 
00184 // ----------------------------------------------------------------------------
00185 
00186 class _scv_tr_generator_core {
00187   friend class scv_tr_stream;
00188  public:
00189   uint64 my_id;
00190   char* my_name;
00191   _scv_tr_stream_core* my_scv_tr_stream_core_p;
00192   scv_tr_generator_base* my_scv_tr_generator_base_p;
00193   static _scv_tr_callback_list* callback_list_p;
00194   const scv_extensions_if* begin_exts_p;
00195   const scv_extensions_if* end_exts_p;
00196   static int debug;
00197   char* my_begin_attribute_name; 
00198   char* my_end_attribute_name;
00199 
00200   _scv_tr_generator_core(
00201     _scv_tr_stream_core* scv_tr_stream_core_p,
00202     scv_tr_generator_base* scv_tr_generator_base_p,
00203     const char* name,
00204     const char* begin_attribute_name,
00205     const char* end_attribute_name);
00206 };
00207 
00208 int _scv_tr_generator_core::debug = -1;
00209 _scv_tr_callback_list* _scv_tr_generator_core::callback_list_p = NULL;
00210 
00211 // ----------------------------------------------------------------------------
00212 
00213 _scv_tr_generator_core::_scv_tr_generator_core(
00214         _scv_tr_stream_core* scv_tr_stream_core_p,
00215         scv_tr_generator_base* scv_tr_generator_base_p,
00216         const char* name,
00217         const char* begin_attribute_name,
00218         const char* end_attribute_name)
00219 {
00220 #ifdef scv_tr_TRACE
00221   cout << "Entering _scv_tr_generator_core ctor\n";
00222 #endif
00223 
00224   if ( (scv_tr_stream_core_p == NULL) ||
00225                 (scv_tr_generator_base_p == NULL) ||
00226                 (scv_tr_stream_core_p->my_scv_tr_db_core_p == NULL) ) {
00227 
00228     scv_tr_null_scv_tr_db_message();
00229 
00230     this->my_scv_tr_stream_core_p = NULL;
00231     this->my_scv_tr_generator_base_p = NULL;
00232     this->begin_exts_p = NULL;
00233     this->end_exts_p = NULL;
00234     this->my_id = 1;
00235     return;
00236   }
00237 
00238   this->my_scv_tr_stream_core_p = scv_tr_stream_core_p;
00239   this->my_scv_tr_generator_base_p = scv_tr_generator_base_p;
00240   this->my_name = scv_tr_strdup(name);
00241   this->begin_exts_p = NULL;
00242   this->end_exts_p = NULL;
00243   this->my_id = scv_tr_stream_core_p->my_scv_tr_db_core_p->global_id++;
00244 
00245   this->my_begin_attribute_name = scv_tr_strdup(begin_attribute_name);
00246   this->my_end_attribute_name = scv_tr_strdup(end_attribute_name);
00247 
00248 #ifdef scv_tr_TRACE
00249   cout << "Leaving _scv_tr_generator_core ctor\n";
00250 #endif
00251 }
00252 
00253 // ----------------------------------------------------------------------------
00254 
00255 class _scv_tr_handle_core {
00256  public:
00257   sc_time begin_sc_time;
00258   sc_time end_sc_time;
00259 
00260   bool is_valid;
00261   bool is_active;
00262   _scv_tr_generator_core* my_scv_tr_generator_core_p;
00263   static int debug;
00264 
00265   uint64 my_id;
00266 
00267   const scv_extensions_if* begin_exts_p;
00268   const scv_extensions_if* end_exts_p;
00269 
00270   string my_name;
00271 
00272   int ref_count;
00273 
00274   static _scv_tr_callback_list* callback_list_p;
00275   static _scv_tr_callback_list* callback_relation_list_p;
00276   static _scv_tr_callback_list* callback_record_attribute_list_p;
00277 
00278   scv_tr_relation_handle_t immediate_relation_handle;
00279   const scv_tr_handle* immediate_other_transaction_handle_p;
00280 
00281   _scv_tr_handle_core();
00282   ~_scv_tr_handle_core();
00283 };
00284 
00285 int _scv_tr_handle_core::debug = -1;
00286 _scv_tr_callback_list* _scv_tr_handle_core::callback_list_p = NULL;
00287 _scv_tr_callback_list* _scv_tr_handle_core::callback_relation_list_p = NULL;
00288 _scv_tr_callback_list* _scv_tr_handle_core::callback_record_attribute_list_p =
00289             NULL;
00290 
00291 // ----------------------------------------------------------------------------
00292 
00293 _scv_tr_handle_core::_scv_tr_handle_core() :
00294   begin_sc_time(SC_ZERO_TIME), end_sc_time(SC_ZERO_TIME)
00295 {
00296 #ifdef scv_tr_TRACE
00297   cout << "In _scv_tr_handle_core ctor\n";
00298 #endif
00299   this->is_valid = false;
00300   this->is_active = false;
00301   this->my_scv_tr_generator_core_p = NULL;
00302   this->my_id = 0;
00303   this->ref_count = 1;
00304 };
00305 
00306 _scv_tr_handle_core::~_scv_tr_handle_core()
00307 {
00308 #ifdef scv_tr_TRACE
00309   cout << "In _scv_tr_handle_core dtor\n";
00310 #endif
00311 }
00312 
00313 // ----------------------------------------------------------------------------
00314 // ----------------------------------------------------------------------------
00315 
00316 template<
00317   class object_class_parameter_t,
00318   typename callback_reason_parameter_t,
00319   typename callback_function_parameter_t
00320   >
00321 static void process_callbacks(
00322   const object_class_parameter_t& obj,
00323   _scv_tr_callback_list* callback_list_p,
00324   callback_reason_parameter_t callback_reason)
00325 {
00326 #ifdef scv_tr_TRACE
00327   cout << "Entering scv_tr process_callbacks\n";
00328 #endif
00329 
00330   // This is a template function that processes callbacks for different
00331   // scv_tr_... classes.
00332 
00333   if (callback_list_p != NULL) {
00334     bool need_cleanup = false;
00335 
00336     _scv_tr_callback_list::iterator i = callback_list_p->begin();
00337 
00338     for ( ; i != callback_list_p->end(); i++) {
00339       if ( (*i)->callback_fp == NULL) {
00340         // This callback has been removed, so we need to clean up after
00341         // this iterator.  We can't remove it here because that would
00342         // corrupt the iterator.
00343         need_cleanup = true;
00344       } else {
00345 
00346         if (obj.get_debug() >= 0) {
00347           cout << "scv_tr debug: process_callbacks" << endl;
00348         }
00349 
00350         callback_function_parameter_t* my_callback_fp =
00351     (callback_function_parameter_t*)((*i)->callback_fp);
00352 
00353 #ifdef scv_tr_TRACE
00354   cout << "  calling my_callback_fp = " << (long)my_callback_fp << endl;
00355   cout << "  obj.get_name() = " << obj.get_name() << endl;
00356 #endif
00357 
00358   my_callback_fp(
00359     obj,
00360     callback_reason,
00361     (*i)->user_data_p);
00362       }
00363     }
00364 
00365     while (need_cleanup == true) {
00366       // Iterate on the list looking for items that have been marked as
00367       // removed, and then remove them.
00368 
00369       i = callback_list_p->begin();
00370 
00371       for ( ; i != callback_list_p->end(); i++) {
00372         if ( (*i)->callback_fp == NULL) {
00373           delete *i;
00374           callback_list_p->erase(i);
00375           goto continue_label;
00376         }
00377       }
00378       // If you get here, then there are no more items to remove.
00379       need_cleanup = false;
00380 
00381       continue_label: ;
00382     }
00383   }
00384 
00385 #ifdef scv_tr_TRACE
00386   cout << "Leaving process_callbacks\n";
00387 #endif
00388 }
00389 
00390 // ----------------------------------------------------------------------------
00391 
00392 static void process_record_attribute_callbacks(
00393         const scv_tr_handle& obj,
00394         const char* attribute_name,
00395         _scv_tr_callback_list* callback_list_p,
00396   const scv_extensions_if* my_exts_p)
00397 {
00398   // This function processes record_attribute callbacks.
00399 
00400   if (callback_list_p != NULL) {
00401     bool need_cleanup = false;
00402 
00403     _scv_tr_callback_list::iterator i = callback_list_p->begin();
00404 
00405     for ( ; i != callback_list_p->end(); i++) {
00406       if ( (*i)->callback_fp == NULL) {
00407         // This callback has been removed, so we need to clean up after
00408         // this iterator.  We can't remove it here because that would
00409         // corrupt the iterator.
00410         need_cleanup = true;
00411       } else {
00412         scv_tr_handle::callback_record_attribute_function* my_callback_fp =
00413                 (scv_tr_handle::callback_record_attribute_function*)
00414       ((*i)->callback_fp);
00415         my_callback_fp(
00416                 obj,
00417     attribute_name,
00418     my_exts_p,
00419                 (*i)->user_data_p);
00420       }
00421     }
00422 
00423     while (need_cleanup == true) {
00424       // Iterate on the list looking for items that have been marked as
00425       // removed, and then remove them.
00426 
00427       i = callback_list_p->begin();
00428 
00429       for ( ; i != callback_list_p->end(); i++) {
00430         if ( (*i)->callback_fp == NULL) {
00431           delete *i;
00432           callback_list_p->erase(i);
00433           goto continue_label;
00434         }
00435       }
00436       // If you get here, then there are no more items to remove.
00437       need_cleanup = false;
00438 
00439       continue_label: ;
00440     }
00441   }
00442 }
00443 
00444 // ----------------------------------------------------------------------------
00445 
00446 static void process_relation_callbacks(
00447         const scv_tr_handle& obj,
00448         const scv_tr_handle& obj_2,
00449         _scv_tr_callback_list* callback_list_p,
00450         scv_tr_relation_handle_t relation_handle)
00451 {
00452   // This is a function that processes callbacks for scv_tr_handle:add_relation
00453 
00454   if (callback_list_p != NULL) {
00455     bool need_cleanup = false;
00456 
00457     _scv_tr_callback_list::iterator i = callback_list_p->begin();
00458 
00459     for ( ; i != callback_list_p->end(); i++) {
00460       if ( (*i)->callback_fp == NULL) {
00461         // This callback has been removed, so we need to clean up after
00462         // this iterator.  We can't remove it here because that would
00463         // corrupt the iterator.
00464         need_cleanup = true;
00465       } else {
00466         scv_tr_handle::callback_relation_function* my_callback_fp =
00467                 (scv_tr_handle::callback_relation_function*)((*i)->callback_fp);
00468 
00469         my_callback_fp(
00470                 obj,
00471     obj_2,
00472                 (*i)->user_data_p,
00473     relation_handle);
00474       }
00475     }
00476 
00477     while (need_cleanup == true) {
00478       // Iterate on the list looking for items that have been marked as
00479       // removed, and then remove them.
00480 
00481       i = callback_list_p->begin();
00482 
00483       for ( ; i != callback_list_p->end(); i++) {
00484         if ( (*i)->callback_fp == NULL) {
00485           delete *i;
00486           callback_list_p->erase(i);
00487           goto continue_label;
00488         }
00489       }
00490       // If you get here, then there are no more items to remove.
00491       need_cleanup = false;
00492 
00493       continue_label: ;
00494     }
00495   }
00496 }
00497 
00498 // ----------------------------------------------------------------------------
00499 // ----------------------------------------------------------------------------
00500 
00501 const char *scv_tr_db::_kind = "scv_tr_db";
00502 
00503 scv_tr_db::scv_tr_db(
00504   const char* recording_file_name,
00505   const sc_time_unit& _time_unit)
00506 {
00507   if (this->get_debug() >= 0) {
00508     cout << "scv_tr debug: entering scv_tr_db ctor, name = " <<
00509         recording_file_name << endl;
00510   }
00511 
00512   this->_scv_tr_db_core_p = new _scv_tr_db_core(
00513     recording_file_name,
00514     _time_unit);
00515 
00516   if (_scv_tr_db_core::default_scv_tr_db_p == NULL) {
00517    _scv_tr_db_core::default_scv_tr_db_p = this;
00518   }
00519 
00520   this->_scv_tr_db_core_p->my_scv_tr_db_p = this;
00521 
00522   // Make any need callbacks:
00523 
00524   process_callbacks<
00525     scv_tr_db,
00526     scv_tr_db::callback_reason,
00527     scv_tr_db::callback_function> (
00528     *this,
00529     _scv_tr_db_core::callback_list_p,
00530     scv_tr_db::CREATE);
00531 
00532   if (this->get_debug() >= 0) {
00533     cout << "scv_tr debug: leaving scv_tr_db ctor, name = " <<
00534                         recording_file_name << endl;
00535   }
00536 }
00537 
00538 // ----------------------------------------------------------------------------
00539 
00540 scv_tr_db::~scv_tr_db()
00541 {
00542   int d = this->get_debug();
00543 
00544   if (d >= 0) {
00545     cout << "scv_tr debug: entering scv_tr_db dtor, name = " <<
00546   this->get_name() << endl;
00547   }
00548 
00549   if (_scv_tr_db_core::default_scv_tr_db_p == this) {
00550     _scv_tr_db_core::default_scv_tr_db_p = NULL;
00551   }
00552 
00553   process_callbacks<
00554                 scv_tr_db,
00555                 scv_tr_db::callback_reason,
00556                 scv_tr_db::callback_function> (
00557                 *this,
00558                 _scv_tr_db_core::callback_list_p,
00559                 scv_tr_db::DELETE);
00560 
00561   delete this->_scv_tr_db_core_p;
00562 
00563   if (d >= 0) {
00564     cout << "scv_tr debug: leaving scv_tr_db dtor" << endl;
00565   }
00566 }
00567 
00568 // ----------------------------------------------------------------------------
00569 
00570 scv_tr_db::callback_h scv_tr_db::register_class_cb(
00571         scv_tr_db::callback_function* cbf,
00572         void* user_data_p)
00573 {
00574   if (_scv_tr_db_core::callback_list_p == NULL) {
00575     _scv_tr_db_core::callback_list_p = new _scv_tr_callback_list;
00576   }
00577 
00578   _scv_tr_callback_item_t* my_item_p = new _scv_tr_callback_item_t;
00579 
00580   my_item_p->callback_fp = (void*) cbf;
00581   my_item_p->user_data_p = (void*) user_data_p;
00582 
00583   _scv_tr_db_core::callback_list_p->push_back(my_item_p);
00584 
00585   return my_item_p->id;
00586 }
00587 
00588 // ----------------------------------------------------------------------------
00589 
00590 void scv_tr_db::set_default_db(scv_tr_db* db)
00591 {
00592   _scv_tr_db_core::default_scv_tr_db_p = db;
00593 }
00594 
00595 // ----------------------------------------------------------------------------
00596 
00597 scv_tr_db* scv_tr_db::get_default_db()
00598 {
00599   return _scv_tr_db_core::default_scv_tr_db_p;
00600 }
00601 
00602 // ----------------------------------------------------------------------------
00603 
00604 void scv_tr_db::set_recording(bool b) const
00605 {
00606   if (this->_scv_tr_db_core_p == NULL) return;
00607 
00608   this->_scv_tr_db_core_p->state = b; // true is to resume recording
00609 }
00610 
00611 // ----------------------------------------------------------------------------
00612 
00613 bool scv_tr_db::get_recording() const
00614 {
00615   if (this->_scv_tr_db_core_p == NULL) return false;
00616 
00617   return this->_scv_tr_db_core_p->state;
00618 }
00619 
00620 // ----------------------------------------------------------------------------
00621 
00622 void scv_tr_db::print(ostream& o, int details, int indent) const
00623 {
00624   o << "scv_tr_db: " << this->get_name() << endl;
00625 }
00626 
00627 // ----------------------------------------------------------------------------
00628 
00629 void scv_tr_db::show(int details, int indent) const
00630 {
00631   this->print(scv_out, details, indent);
00632 }
00633 
00634 // ----------------------------------------------------------------------------
00635 
00636 void scv_tr_db::set_debug(int d)
00637 {
00638   scv_debug::set_facility_level(scv_debug::RECORDING, d);
00639 
00640   _scv_tr_db_core::debug = d;
00641 }
00642 
00643 // ----------------------------------------------------------------------------
00644 
00645 int scv_tr_db::get_debug()
00646 {
00647   return _scv_tr_db_core::debug;
00648 }
00649 
00650 // ----------------------------------------------------------------------------
00651 
00652 const char *scv_tr_db::get_name() const
00653 {
00654   if (this->_scv_tr_db_core_p == NULL) {
00655     static string tmp_name = "<anonymous>";
00656     return tmp_name.c_str();
00657   }
00658 
00659   static string tmp_my_name;
00660   tmp_my_name = this->_scv_tr_db_core_p->my_name;
00661   return tmp_my_name.c_str();
00662 }
00663 
00664 // ----------------------------------------------------------------------------
00665 
00666 void scv_tr_db::remove_callback(callback_h h)
00667 {
00668   _scv_tr_callback_list* my_cb_list_p = _scv_tr_db_core::callback_list_p;
00669 
00670   if (my_cb_list_p == NULL) return;
00671 
00672   _scv_tr_callback_list::iterator i = my_cb_list_p->begin();
00673 
00674   for ( ; i != my_cb_list_p->end(); i++) {
00675     if ((*i)->id == h) {
00676       // The entry gets deleted the next time callbacks get processed -
00677       // you can't delete here because you might currently be in the middle of
00678       // a callback, and that would screw up the list if the item were deleted.
00679       (*i)->callback_fp = NULL;
00680     }
00681   }
00682 }
00683 
00684 // ----------------------------------------------------------------------------
00685 // ----------------------------------------------------------------------------
00686 
00687 const char *scv_tr_stream::_kind = "scv_tr_stream";
00688 
00689 scv_tr_stream::scv_tr_stream(
00690         const char* full_stream_name,
00691         const char* kind_name,
00692         scv_tr_db* scv_tr_db_p)
00693 {
00694 #ifdef scv_tr_TRACE
00695   cout << "Entering scv_tr_stream ctor\n";
00696 #endif
00697 
00698   if (scv_tr_db_p == NULL) {
00699     scv_tr_null_scv_tr_db_message();
00700     this->_scv_tr_stream_core_p = NULL;
00701     return;
00702   }
00703 
00704   this->_scv_tr_stream_core_p = new _scv_tr_stream_core(
00705     scv_tr_db_p->_scv_tr_db_core_p,
00706     this,
00707     full_stream_name,
00708     kind_name
00709     );
00710 
00711   process_callbacks<
00712     scv_tr_stream,
00713     scv_tr_stream::callback_reason,
00714     scv_tr_stream::callback_function> (
00715     *this,
00716     _scv_tr_stream_core::callback_list_p,
00717     scv_tr_stream::CREATE);
00718 }
00719 
00720 // ----------------------------------------------------------------------------
00721 
00722 scv_tr_stream::~scv_tr_stream()
00723 {
00724 #ifdef scv_tr_TRACE
00725   cout << "Entering scv_tr_stream dtor\n";
00726 #endif
00727 
00728   process_callbacks<
00729                 scv_tr_stream,
00730                 scv_tr_stream::callback_reason,
00731                 scv_tr_stream::callback_function> (
00732                 *this,
00733                 _scv_tr_stream_core::callback_list_p,
00734                 scv_tr_stream::DELETE);
00735 
00736 #ifdef scv_tr_TRACE
00737   cout << "Leaving scv_tr_stream dtor\n";
00738 #endif
00739 }
00740 
00741 // ----------------------------------------------------------------------------
00742 
00743 scv_tr_stream::callback_h scv_tr_stream::register_class_cb(
00744         scv_tr_stream::callback_function* cbf,
00745         void* user_data_p)
00746 {
00747   if (_scv_tr_stream_core::callback_list_p == NULL) {
00748     _scv_tr_stream_core::callback_list_p = new _scv_tr_callback_list;
00749   }
00750 
00751   _scv_tr_callback_item_t* my_item_p = new _scv_tr_callback_item_t;
00752 
00753   my_item_p->callback_fp = (void*) cbf;
00754   my_item_p->user_data_p = (void*) user_data_p;
00755 
00756   _scv_tr_stream_core::callback_list_p->push_back(my_item_p);
00757 
00758   return my_item_p->id;
00759 }
00760 
00761 // ----------------------------------------------------------------------------
00762 
00763 void scv_tr_stream::print(ostream& o, int details, int indent) const
00764 {
00765   o << "scv_tr_stream:" << this->get_name() << endl;
00766 }
00767 
00768 // ----------------------------------------------------------------------------
00769 
00770 void scv_tr_stream::show(int details, int indent) const
00771 {
00772   this->print(scv_out, details, indent);
00773 }
00774 
00775 // ----------------------------------------------------------------------------
00776 
00777 void scv_tr_stream::set_debug(int i) 
00778 {
00779   _scv_tr_stream_core::debug = i;
00780 }
00781 
00782 // ----------------------------------------------------------------------------
00783 
00784 int scv_tr_stream::get_debug()
00785 {
00786   return _scv_tr_stream_core::debug;
00787 }
00788 
00789 // ----------------------------------------------------------------------------
00790 
00791 const char *scv_tr_stream::get_name() const
00792 {
00793   if (this->_scv_tr_stream_core_p == NULL) {
00794     static string tmp_name = "<anonymous>";
00795     return tmp_name.c_str();
00796   }
00797 
00798   static string tmp_my_name;
00799   tmp_my_name = this->_scv_tr_stream_core_p->my_name;
00800   return tmp_my_name.c_str();
00801 }
00802 
00803 // ----------------------------------------------------------------------------
00804 
00805 uint64 scv_tr_stream::get_id() const
00806 {
00807   if (this->_scv_tr_stream_core_p == NULL) return 0;
00808 
00809   return this->_scv_tr_stream_core_p->my_id;
00810 }
00811 
00812 // ----------------------------------------------------------------------------
00813 
00814 const char* scv_tr_stream::get_stream_kind() const
00815 {
00816   if (this->_scv_tr_stream_core_p == NULL) return NULL;
00817   return this->_scv_tr_stream_core_p->my_stream_kind_name;
00818 }
00819 
00820 // ----------------------------------------------------------------------------
00821 
00822 void scv_tr_stream::remove_callback(callback_h h)
00823 {
00824   _scv_tr_callback_list* my_cb_list_p = _scv_tr_stream_core::callback_list_p;
00825 
00826   if (my_cb_list_p == NULL) return;
00827 
00828   _scv_tr_callback_list::iterator i = my_cb_list_p->begin();
00829 
00830   for ( ; i != my_cb_list_p->end(); i++) {
00831     if ((*i)->id == h) {
00832       // The entry gets deleted the next time callbacks get processed -
00833       // you can't delete here because you might currently be in the middle of
00834       // a callback, and that would screw up the list if the item were deleted.
00835       (*i)->callback_fp = NULL;
00836     }
00837   }
00838 }
00839 
00840 // ----------------------------------------------------------------------------
00841 // ----------------------------------------------------------------------------
00842 
00843 const char *scv_tr_handle::_kind = "scv_tr_handle";
00844 
00845 scv_tr_handle::scv_tr_handle()
00846 {
00847 #ifdef scv_tr_TRACE
00848   cout << "Entering scv_tr_handle ctor\n";
00849 #endif
00850 
00851   this->_scv_tr_handle_core_p = NULL;
00852 
00853 #ifdef scv_tr_TRACE
00854   cout << "Leaving scv_tr_handle ctor\n";
00855 #endif
00856 }
00857 
00858 // ----------------------------------------------------------------------------
00859 
00860 scv_tr_handle::~scv_tr_handle()
00861 {
00862 #ifdef scv_tr_TRACE
00863   cout << "Entering scv_tr_handle dtor\n";
00864   cout << "  this->get_id() = " << this->get_id() << endl;
00865 #endif
00866 
00867   if (this->_scv_tr_handle_core_p != NULL) {
00868 
00869 #ifdef scv_tr_TRACE
00870   cout << "  this->_scv_tr_handle_core_p->ref_count = "
00871   << _scv_tr_handle_core_p->ref_count << endl;
00872 #endif
00873 
00874     if (this->_scv_tr_handle_core_p->ref_count == 1) {
00875 
00876       process_callbacks<
00877                 scv_tr_handle,
00878                 scv_tr_handle::callback_reason,
00879                 scv_tr_handle::callback_function> (
00880                 *this,
00881                 _scv_tr_handle_core::callback_list_p,
00882                 scv_tr_handle::DELETE);
00883 
00884       if (this->_scv_tr_handle_core_p->ref_count != 1) {
00885         _scv_message::message(
00886                 _scv_message::TRANSACTION_RECORDING_INTERNAL_FATAL,
00887                 "scv_tr_handle::~scv_tr_handle ref_count bad");
00888 
00889         return;
00890       }
00891 
00892 #ifdef scv_tr_TRACE
00893   cout << "  delete _scv_tr_handle_core_p\n";
00894 #endif
00895 
00896       delete this->_scv_tr_handle_core_p;
00897     } else {
00898       this->_scv_tr_handle_core_p->ref_count--;
00899 
00900 #ifdef scv_tr_TRACE
00901   cout << "  new this->_scv_tr_handle_core_p->ref_count = "
00902         << _scv_tr_handle_core_p->ref_count << endl;
00903 #endif
00904     }
00905   }
00906 
00907 #ifdef scv_tr_TRACE
00908   cout << "Leaving scv_tr_handle dtor\n";
00909 #endif
00910 }
00911 
00912 // ----------------------------------------------------------------------------
00913 
00914 scv_tr_handle &scv_tr_handle::operator=(
00915     const scv_tr_handle& other)
00916 {
00917   // Copy assign
00918 
00919 #ifdef scv_tr_TRACE
00920   cout << "scv_tr_handle operator=\n";
00921   cout << "  other.get_id() = " << other.get_id() << endl;
00922 #endif
00923 
00924   if (this == &other) {
00925 #ifdef scv_tr_TRACE
00926   cout << "Leaving scv_tr_handle operator=, this == &other\n";
00927 #endif
00928     return *this;
00929   }
00930 
00931   if (this->_scv_tr_handle_core_p != NULL) {
00932 
00933 #ifdef scv_tr_TRACE
00934   cout << "  this->get_id() = " << this->get_id() << endl;
00935   cout << "  this->_scv_tr_handle_core_p->ref_count = "
00936   << this->_scv_tr_handle_core_p->ref_count << endl;
00937 #endif
00938 
00939     this->_scv_tr_handle_core_p->ref_count--;
00940 
00941     if (this->_scv_tr_handle_core_p->ref_count == 0) {
00942 
00943       process_callbacks<
00944                 scv_tr_handle,
00945                 scv_tr_handle::callback_reason,
00946                 scv_tr_handle::callback_function> (
00947                 *this,
00948                 _scv_tr_handle_core::callback_list_p,
00949                 scv_tr_handle::DELETE);
00950 
00951 #ifdef scv_tr_TRACE
00952   cout << "  In scv_tr_handle operator= after process_callbacks\n"
00953   << "  this->_scv_tr_handle_core_p->ref_count = "
00954         << this->_scv_tr_handle_core_p->ref_count << endl;
00955 #endif
00956 
00957       if (this->_scv_tr_handle_core_p->ref_count != 0) {
00958         _scv_message::message(
00959         _scv_message::TRANSACTION_RECORDING_INTERNAL_FATAL,
00960   "scv_tr_handle::operator= ref_count is bad after process_callbacks");
00961 
00962         return *this;
00963       }
00964 
00965       delete this->_scv_tr_handle_core_p;
00966     }
00967   }
00968 
00969   this->_scv_tr_handle_core_p = other._scv_tr_handle_core_p;
00970 
00971   if (this->_scv_tr_handle_core_p != NULL) {
00972 
00973     this->_scv_tr_handle_core_p->ref_count++;
00974 
00975 #ifdef scv_tr_TRACE
00976   cout << "  In scv_tr_handle operator= after process_callbacks\n"
00977         << "  new other._scv_tr_handle_core_p->ref_count = "
00978         << other._scv_tr_handle_core_p->ref_count << endl;
00979 #endif
00980   }
00981 
00982   return *this;
00983 }
00984 
00985 // ----------------------------------------------------------------------------
00986 
00987 scv_tr_handle::scv_tr_handle(
00988     const scv_tr_handle& other)
00989 {
00990   // Copy ctor
00991 
00992 #ifdef scv_tr_TRACE
00993   cout << "Entering scv_tr_handle copy ctor\n";
00994   cout << "  other.get_id() = " << other.get_id() << endl;
00995 #endif
00996 
00997   this->_scv_tr_handle_core_p = other._scv_tr_handle_core_p;
00998 
00999   if (this->_scv_tr_handle_core_p) {
01000 
01001     this->_scv_tr_handle_core_p->ref_count++;
01002 
01003 #ifdef scv_tr_TRACE
01004   cout << "  new this->_scv_tr_handle_core_p->ref_count = "
01005         << this->_scv_tr_handle_core_p->ref_count << endl;
01006 #endif
01007   }
01008 
01009 #ifdef scv_tr_TRACE
01010   cout << "Leaving scv_tr_handle copy ctor\n";
01011 #endif
01012 }
01013 
01014 // ----------------------------------------------------------------------------
01015 
01016 void scv_tr_handle::_record_attribute(
01017   const char* attribute_name,
01018   const scv_extensions_if* my_exts_p)
01019 {
01020   const char* tmp_attribute_name =
01021         attribute_name ? attribute_name : "<anonymous>";
01022 
01023   process_record_attribute_callbacks(
01024                 *this,
01025                 tmp_attribute_name,
01026                 _scv_tr_handle_core::callback_record_attribute_list_p,
01027     my_exts_p);
01028 }
01029 
01030 // ----------------------------------------------------------------------------
01031 
01032 scv_tr_handle::callback_h scv_tr_handle::register_class_cb(
01033         scv_tr_handle::callback_function* cbf,
01034   void* user_data_p)
01035 {
01036   if (_scv_tr_handle_core::callback_list_p == NULL) {
01037     _scv_tr_handle_core::callback_list_p = new _scv_tr_callback_list;
01038   }
01039 
01040   _scv_tr_callback_item_t* my_item_p = new _scv_tr_callback_item_t;
01041 
01042   my_item_p->callback_fp = (void*) cbf;
01043   my_item_p->user_data_p = (void*) user_data_p;
01044 
01045   _scv_tr_handle_core::callback_list_p->push_back(my_item_p);
01046 
01047   return my_item_p->id;
01048 }
01049 
01050 // ----------------------------------------------------------------------------
01051 
01052 scv_tr_handle::callback_h scv_tr_handle::register_record_attribute_cb(
01053         scv_tr_handle::callback_record_attribute_function* cbf,
01054         void* user_data_p)
01055 {
01056   if (_scv_tr_handle_core::callback_record_attribute_list_p == NULL) {
01057     _scv_tr_handle_core::callback_record_attribute_list_p =
01058           new _scv_tr_callback_list;
01059   }
01060 
01061   _scv_tr_callback_item_t* my_item_p = new _scv_tr_callback_item_t;
01062 
01063   my_item_p->callback_fp = (void*) cbf;
01064   my_item_p->user_data_p = (void*) user_data_p;
01065 
01066   _scv_tr_handle_core::callback_record_attribute_list_p->push_back(my_item_p);
01067 
01068   return my_item_p->id;
01069 }
01070 
01071 // ----------------------------------------------------------------------------
01072 
01073 scv_tr_handle::callback_h scv_tr_handle::register_relation_cb(
01074   scv_tr_handle::callback_relation_function* cbf,
01075         void* user_data_p)
01076 {
01077   if (_scv_tr_handle_core::callback_relation_list_p == NULL) {
01078     _scv_tr_handle_core::callback_relation_list_p = new _scv_tr_callback_list;
01079   }
01080 
01081   _scv_tr_callback_item_t* my_item_p = new _scv_tr_callback_item_t;
01082 
01083   my_item_p->callback_fp = (void*) cbf;
01084   my_item_p->user_data_p = (void*) user_data_p;
01085 
01086   _scv_tr_handle_core::callback_relation_list_p->push_back(my_item_p);
01087 
01088   return my_item_p->id;
01089 }
01090 
01091 // ----------------------------------------------------------------------------
01092 
01093 bool scv_tr_handle::is_valid() const
01094 {
01095   if (this->_scv_tr_handle_core_p) {
01096     return this->_scv_tr_handle_core_p->is_valid;
01097   } else {
01098     return false;
01099   }
01100 }
01101 
01102 // ----------------------------------------------------------------------------
01103 
01104 bool scv_tr_handle::is_active() const
01105 {
01106   if (this->_scv_tr_handle_core_p) {
01107     return this->_scv_tr_handle_core_p->is_active;
01108   } else {
01109     return false;
01110   }
01111 }
01112 
01113 // ----------------------------------------------------------------------------
01114 
01115 const scv_extensions_if* scv_tr_handle::get_begin_exts_p() const
01116 {
01117   if (this->_scv_tr_handle_core_p == NULL) return NULL;
01118 
01119   return this->_scv_tr_handle_core_p->begin_exts_p;
01120 }
01121 
01122 // ----------------------------------------------------------------------------
01123 
01124 const scv_extensions_if* scv_tr_handle::get_end_exts_p() const
01125 {
01126   if (this->_scv_tr_handle_core_p == NULL) return NULL;
01127 
01128   return this->_scv_tr_handle_core_p->end_exts_p;
01129 }
01130 
01131 // ----------------------------------------------------------------------------
01132 
01133 uint64 scv_tr_handle::get_id() const
01134 {
01135   if (this->_scv_tr_handle_core_p) return this->_scv_tr_handle_core_p->my_id;
01136   else return 0;
01137 }
01138 
01139 // ----------------------------------------------------------------------------
01140 
01141 void scv_tr_handle::print(ostream& o, int details, int indent) const
01142 {
01143   o << "scv_tr_handle: " << this->get_name() << endl;
01144 }
01145 
01146 // ----------------------------------------------------------------------------
01147 
01148 void scv_tr_handle::show(int details, int indent) const
01149 {
01150   this->print(scv_out, details, indent);
01151 }
01152 
01153 // ----------------------------------------------------------------------------
01154 
01155 void scv_tr_handle::set_debug(int i) 
01156 {
01157   _scv_tr_handle_core::debug = i;
01158 }
01159 
01160 // ----------------------------------------------------------------------------
01161 
01162 int scv_tr_handle::get_debug()
01163 {
01164   return _scv_tr_handle_core::debug;
01165 }
01166 
01167 // ----------------------------------------------------------------------------
01168 
01169 const char *scv_tr_handle::get_name() const
01170 {
01171   if (this->_scv_tr_handle_core_p == NULL) {
01172     static string tmp_name = "<anonymous>";
01173     return tmp_name.c_str();
01174   }
01175 
01176   return this->_scv_tr_handle_core_p->my_name.c_str();
01177 }
01178 
01179 // ----------------------------------------------------------------------------
01180 
01181 bool scv_tr_handle::add_relation(
01182         scv_tr_relation_handle_t relation_handle,
01183         const scv_tr_handle& other_transaction)
01184 {
01185   process_relation_callbacks(
01186                 *this,
01187     other_transaction,
01188                 _scv_tr_handle_core::callback_relation_list_p,
01189                 relation_handle);
01190 
01191   return true;
01192 }
01193 
01194 // ----------------------------------------------------------------------------
01195 
01196 const scv_tr_handle* scv_tr_handle::get_immediate_related_transaction(
01197         scv_tr_relation_handle_t* relation_handle_p) const
01198 {
01199   *relation_handle_p = this->_scv_tr_handle_core_p->immediate_relation_handle;
01200   return this->_scv_tr_handle_core_p->immediate_other_transaction_handle_p;
01201 }
01202 
01203 // ----------------------------------------------------------------------------
01204 
01205 const sc_time& scv_tr_handle::get_begin_sc_time() const
01206 {
01207 #ifdef scv_tr_TRACE
01208   cout << "Entering scv_tr_handle::get_begin_sc_time\n";
01209 #endif
01210 
01211   if (this->_scv_tr_handle_core_p == NULL) {
01212 
01213 #ifdef scv_tr_TRACE
01214   cout << "  this->_scv_tr_handle_core_p is NULL\n";
01215 #endif
01216 
01217     static sc_time tmp_sc_time;
01218     return tmp_sc_time;
01219   }
01220 
01221 #ifdef scv_tr_TRACE
01222   cout << "Leaving scv_tr_handle::get_begin_sc_time\n";
01223 #endif
01224 
01225   return this->_scv_tr_handle_core_p->begin_sc_time;
01226 }
01227 
01228 // ----------------------------------------------------------------------------
01229 
01230 const sc_time& scv_tr_handle::get_end_sc_time() const
01231 {
01232   if (this->_scv_tr_handle_core_p == NULL) {
01233     static sc_time tmp_sc_time;
01234     return tmp_sc_time;
01235   }
01236 
01237   return this->_scv_tr_handle_core_p->end_sc_time;
01238 }
01239 
01240 // ----------------------------------------------------------------------------
01241 
01242 const scv_tr_stream& scv_tr_handle::get_scv_tr_stream() const
01243 {
01244   if ( (this->_scv_tr_handle_core_p == NULL) ||
01245   (this->_scv_tr_handle_core_p->my_scv_tr_generator_core_p == NULL) ){
01246     scv_tr_null_scv_tr_db_message();
01247     static scv_tr_stream* tmp_stream_p = new scv_tr_stream();
01248     return *tmp_stream_p;
01249   }
01250 
01251   return *(this->_scv_tr_handle_core_p->my_scv_tr_generator_core_p->
01252       my_scv_tr_stream_core_p->my_scv_tr_stream_p);
01253 }
01254 
01255 // ----------------------------------------------------------------------------
01256 
01257 const scv_tr_generator_base&
01258     scv_tr_handle::get_scv_tr_generator_base() const
01259 {
01260   if ( (this->_scv_tr_handle_core_p == NULL) ||
01261   (this->_scv_tr_handle_core_p->my_scv_tr_generator_core_p == NULL) ) {
01262     scv_tr_null_scv_tr_db_message();
01263     static scv_tr_generator_base* tmp_generator_base_p =
01264           new scv_tr_generator_base();
01265     return *tmp_generator_base_p;
01266   }
01267 
01268   return *(this->_scv_tr_handle_core_p->my_scv_tr_generator_core_p->
01269                         my_scv_tr_generator_base_p);
01270 }
01271 
01272 // ----------------------------------------------------------------------------
01273 
01274 void scv_tr_handle::remove_callback(callback_h h)
01275 {
01276   // There are 3 callback lists in scv_tr_handle
01277 
01278   {
01279   _scv_tr_callback_list* my_cb_list_p = _scv_tr_handle_core::callback_list_p;
01280 
01281   if (my_cb_list_p != NULL) {
01282 
01283   _scv_tr_callback_list::iterator i = my_cb_list_p->begin();
01284 
01285   for ( ; i != my_cb_list_p->end(); i++) {
01286     if ((*i)->id == h) {
01287       // The entry gets deleted the next time callbacks get processed -
01288       // you can't delete here because you might currently be in the middle of
01289       // a callback, and that would screw up the list if the item were deleted.
01290       (*i)->callback_fp = NULL;
01291       return;
01292     }
01293   }
01294   }
01295   }
01296 
01297   {
01298   _scv_tr_callback_list* my_cb_list_p =
01299         _scv_tr_handle_core::callback_relation_list_p;
01300 
01301   if (my_cb_list_p != NULL) {
01302 
01303   _scv_tr_callback_list::iterator i = my_cb_list_p->begin();
01304 
01305   for ( ; i != my_cb_list_p->end(); i++) {
01306     if ((*i)->id == h) {
01307       // The entry gets deleted the next time callbacks get processed -
01308       // you can't delete here because you might currently be in the middle of
01309       // a callback, and that would screw up the list if the item were deleted.
01310       (*i)->callback_fp = NULL;
01311       return;
01312     }
01313   }
01314   }
01315   }
01316 
01317   {
01318   _scv_tr_callback_list* my_cb_list_p =
01319       _scv_tr_handle_core::callback_record_attribute_list_p;
01320 
01321   if (my_cb_list_p != NULL) {
01322 
01323   _scv_tr_callback_list::iterator i = my_cb_list_p->begin();
01324 
01325   for ( ; i != my_cb_list_p->end(); i++) {
01326     if ((*i)->id == h) {
01327       // The entry gets deleted the next time callbacks get processed -
01328       // you can't delete here because you might currently be in the middle of
01329       // a callback, and that would screw up the list if the item were deleted.
01330       (*i)->callback_fp = NULL;
01331       return;
01332     }
01333   }
01334   }
01335   }
01336 }
01337 
01338 // ----------------------------------------------------------------------------
01339 
01340 void scv_tr_handle::_end_transaction(
01341   const scv_extensions_if* exts_p,
01342   const sc_time& end_sc_time) const
01343 {
01344   this->get_scv_tr_generator_base()._end_transaction(*this, exts_p, end_sc_time);
01345 }
01346 
01347 // ----------------------------------------------------------------------------
01348 // ----------------------------------------------------------------------------
01349 
01350 scv_tr_handle scv_tr_generator_base::_begin_transaction(
01351                 const scv_extensions_if* ext_p,
01352     const sc_time& begin_sc_time,
01353           scv_tr_relation_handle_t relation_handle,
01354     const scv_tr_handle* other_handle_p) const
01355 {
01356 #ifdef scv_tr_TRACE
01357   cout << "Entering scv_tr_generator_base::_begin_transaction\n";
01358   cout << "  begin_sc_time = " << begin_sc_time.value() << endl;
01359 #endif
01360 
01361   scv_tr_handle tp;
01362 
01363   if ( (this->_scv_tr_generator_core_p == NULL) ||
01364   (this->_scv_tr_generator_core_p->my_scv_tr_stream_core_p == NULL) ||
01365         (this->_scv_tr_generator_core_p->my_scv_tr_stream_core_p->
01366             my_scv_tr_db_core_p == NULL) ) {
01367 #ifdef scv_tr_TRACE
01368   cout << "Leaving scv_tr_generator_base::_begin_transaction, NULL core\n";
01369 #endif
01370     return tp;
01371   }
01372 
01373   tp._scv_tr_handle_core_p = new _scv_tr_handle_core;
01374 
01375   tp._scv_tr_handle_core_p->my_scv_tr_generator_core_p = 
01376     this->_scv_tr_generator_core_p;
01377 
01378   tp._scv_tr_handle_core_p->is_valid = true;
01379   tp._scv_tr_handle_core_p->is_active = true;
01380   tp._scv_tr_handle_core_p->begin_exts_p = ext_p;
01381 
01382   tp._scv_tr_handle_core_p->begin_sc_time = begin_sc_time;
01383 
01384   tp._scv_tr_handle_core_p->my_name =
01385     this->_scv_tr_generator_core_p->my_name;
01386 
01387   tp._scv_tr_handle_core_p->my_id = this->_scv_tr_generator_core_p->
01388       my_scv_tr_stream_core_p->my_scv_tr_db_core_p->
01389         global_transaction_id++;
01390 
01391   tp._scv_tr_handle_core_p->immediate_relation_handle = relation_handle;
01392   tp._scv_tr_handle_core_p->immediate_other_transaction_handle_p =
01393         other_handle_p;
01394 
01395   process_callbacks<
01396                 scv_tr_handle,
01397                 scv_tr_handle::callback_reason,
01398                 scv_tr_handle::callback_function> (
01399     tp,
01400                 _scv_tr_handle_core::callback_list_p,
01401                 scv_tr_handle::BEGIN);
01402 
01403   if (relation_handle != 0) {
01404     tp.add_relation(relation_handle, *other_handle_p);
01405   }
01406 
01407   tp._scv_tr_handle_core_p->begin_exts_p = NULL;
01408 
01409 #ifdef scv_tr_TRACE
01410   cout << "Leaving scv_tr_generator_base::_begin_transaction\n";
01411 #endif
01412 
01413   return tp;
01414 }
01415 
01416 // ----------------------------------------------------------------------------
01417 
01418 void scv_tr_generator_base::_end_transaction(
01419     const scv_tr_handle& t,
01420                 const scv_extensions_if* ext_p,
01421                 const sc_time& end_sc_time) const
01422 {
01423 #ifdef scv_tr_TRACE
01424   cout << "Entering scv_tr_generator_base::_end_transaction\n";
01425 #endif
01426 
01427   if (t._scv_tr_handle_core_p == NULL) return;
01428 
01429   if (t._scv_tr_handle_core_p->is_active == false) {
01430     scv_out <<
01431 "Error in scv_tr_generator_base::end_transaction, transaction is not active.\n";
01432     return;
01433   }
01434 
01435   t._scv_tr_handle_core_p->end_exts_p = ext_p;
01436   t._scv_tr_handle_core_p->end_sc_time = end_sc_time;
01437 
01438   process_callbacks<
01439                 scv_tr_handle,
01440                 scv_tr_handle::callback_reason,
01441                 scv_tr_handle::callback_function> (
01442                 t,
01443                 _scv_tr_handle_core::callback_list_p,
01444                 scv_tr_handle::END);
01445 
01446   t._scv_tr_handle_core_p->is_active = false;
01447 
01448   t._scv_tr_handle_core_p->end_exts_p = NULL;
01449 
01450 #ifdef scv_tr_TRACE
01451   cout << "Leaving scv_tr_generator_base::_end_transaction\n";
01452 #endif
01453 
01454   return;
01455 }
01456 
01457 // ----------------------------------------------------------------------------
01458 // ----------------------------------------------------------------------------
01459 
01460 scv_tr_generator_base::scv_tr_generator_base(
01461         const char* name,
01462         scv_tr_stream& s,
01463         const char* begin_attribute_name,
01464         const char* end_attribute_name)
01465 {
01466   this->_scv_tr_generator_core_p = new _scv_tr_generator_core(
01467     s._scv_tr_stream_core_p,
01468     this,
01469     name,
01470     begin_attribute_name,
01471     end_attribute_name);
01472 }
01473 
01474 // ----------------------------------------------------------------------------
01475 
01476 void scv_tr_generator_base::_set_begin_exts_p(
01477     const scv_extensions_if* _begin_exts_p)
01478 {
01479   this->_scv_tr_generator_core_p->begin_exts_p = _begin_exts_p;
01480 }
01481 
01482 // ----------------------------------------------------------------------------
01483 
01484 void scv_tr_generator_base::_set_end_exts_p(
01485                 const scv_extensions_if* _end_exts_p)
01486 {
01487   if (this->_scv_tr_generator_core_p == NULL) return;
01488 
01489   this->_scv_tr_generator_core_p->end_exts_p = _end_exts_p;
01490 }
01491 
01492 // ----------------------------------------------------------------------------
01493 
01494 void scv_tr_generator_base::_process_callbacks()
01495 {
01496 #ifdef scv_tr_TRACE
01497   cout << "Entering scv_tr_generator_base::_process_callbacks\n";
01498 #endif
01499 
01500   process_callbacks<
01501                 scv_tr_generator_base,
01502                 scv_tr_generator_base::callback_reason,
01503                 scv_tr_generator_base::callback_function> (
01504                 *this,
01505                 _scv_tr_generator_core::callback_list_p,
01506     scv_tr_generator_base::CREATE);
01507 
01508 #ifdef scv_tr_TRACE
01509   cout << "Leaving scv_tr_generator_base::_process_callbacks\n";
01510 #endif
01511 }
01512 
01513 // ----------------------------------------------------------------------------
01514 
01515 scv_tr_generator_base::~scv_tr_generator_base()
01516 {
01517 #ifdef scv_tr_TRACE
01518   cout << "Entering ~scv_tr_generator_base\n";
01519 #endif
01520 
01521   process_callbacks<
01522                 scv_tr_generator_base,
01523                 scv_tr_generator_base::callback_reason,
01524                 scv_tr_generator_base::callback_function> (
01525                 *this,
01526                 _scv_tr_generator_core::callback_list_p,
01527                 scv_tr_generator_base::DELETE);
01528 
01529 #ifdef scv_tr_TRACE
01530   cout << "Entering ~scv_tr_generator_base\n";
01531 #endif
01532 }
01533 
01534 // ----------------------------------------------------------------------------
01535 
01536 scv_tr_db::callback_h scv_tr_generator_base::register_class_cb(
01537     callback_function* cbf,
01538     void* user_data_p)
01539 {
01540   if (_scv_tr_generator_core::callback_list_p == NULL) {
01541     _scv_tr_generator_core::callback_list_p = new _scv_tr_callback_list;
01542   }
01543 
01544   _scv_tr_callback_item_t* my_item_p = new _scv_tr_callback_item_t;
01545 
01546   my_item_p->callback_fp = (void*) cbf;
01547   my_item_p->user_data_p = (void*) user_data_p;
01548 
01549   _scv_tr_generator_core::callback_list_p->push_back(my_item_p);
01550 
01551   return my_item_p->id;
01552 }
01553 
01554 // ----------------------------------------------------------------------------
01555 
01556 scv_tr_relation_handle_t scv_tr_db::create_relation(
01557         const char* relation_name) const
01558 {
01559   // Create a new relation that can be defined between two transactions.
01560   // If a relation with relation_name had previously been created, then
01561   // return the handle to that relation.
01562 
01563   scv_tr_relation_handle_t tmp_handle =
01564     this->_scv_tr_db_core_p->relation_by_name_map[relation_name];
01565 
01566   if (tmp_handle == 0) {
01567     tmp_handle = ++this->_scv_tr_db_core_p->relation_handle_counter;
01568     this->_scv_tr_db_core_p->relation_by_name_map[relation_name] = tmp_handle;
01569     this->_scv_tr_db_core_p->relation_by_handle_map[tmp_handle] = relation_name;
01570   }
01571 
01572   return tmp_handle;
01573 }
01574 
01575 // ----------------------------------------------------------------------------
01576 
01577 const char* scv_tr_db::get_relation_name(
01578         scv_tr_relation_handle_t relation_handle) const
01579 {
01580   return this->_scv_tr_db_core_p->
01581       relation_by_handle_map[relation_handle].c_str();
01582 }
01583 
01584 // ----------------------------------------------------------------------------
01585 
01586 uint64 scv_tr_generator_base::get_id() const
01587 {
01588   if (this->_scv_tr_generator_core_p == NULL) return 0;
01589   return this->_scv_tr_generator_core_p->my_id;
01590 }
01591 
01592 // ----------------------------------------------------------------------------
01593 
01594 const scv_extensions_if* scv_tr_generator_base::get_begin_exts_p() const
01595 {
01596   if (this->_scv_tr_generator_core_p == NULL) return NULL;
01597 
01598   const scv_extensions_if* my_exts_p =
01599                                 this->_scv_tr_generator_core_p->begin_exts_p;
01600 
01601   // Check if default template parameter is used, if so return NULL:
01602   //
01603   if (my_exts_p->get_type() == scv_extensions_if::RECORD) {
01604     if ( (my_exts_p->get_field(0)->get_type() == scv_extensions_if::INTEGER) &&
01605          ( ! strcmp(my_exts_p->get_field(0)->get_name(),"_default_field_") ) ) {
01606       return NULL;
01607     }
01608   }
01609 
01610   return my_exts_p;
01611 }
01612 
01613 // ----------------------------------------------------------------------------
01614 
01615 const scv_extensions_if* scv_tr_generator_base::get_end_exts_p() const
01616 {
01617   if (this->_scv_tr_generator_core_p == NULL) return NULL;
01618 
01619   const scv_extensions_if* my_exts_p =
01620                                 this->_scv_tr_generator_core_p->end_exts_p;
01621 
01622   // Check if default template parameter is used, if so return NULL:
01623   //
01624   if (my_exts_p->get_type() == scv_extensions_if::RECORD) {
01625     if ( (my_exts_p->get_field(0)->get_type() == scv_extensions_if::INTEGER) &&
01626          ( ! strcmp(my_exts_p->get_field(0)->get_name(),"_default_field_") ) ) {
01627       return NULL;
01628     }
01629   }
01630 
01631   return my_exts_p;
01632 }
01633 
01634 // ----------------------------------------------------------------------------
01635 
01636 const scv_tr_stream& scv_tr_gene