/* PURPOSE: (Illustrate how to checkpoint STLs) LIBRARY_DEPENDENCIES: ( (checkpoint_map.o) ) */ #ifndef CHECKPOINT_MAP_HH #define CHECKPOINT_MAP_HH #include #include #include #include #ifdef __GNUC__ #include #endif #include "sim_services/MemoryManager/include/memorymanager_c_intf.h" #include "sim_services/Message/include/message_proto.h" #ifndef TRICK_ICG /* For all of the checkpoint_map_stl variations. Declare 2 memory manager arrays to hold the contents of the map. No simulation variable actually points to these arrays. Only the user knows they are there and how they are stored. The restart function knows how to "retrieve" and restore the data. The name of the declaration is important. Each instance of the STL requires a unique name to be saved correctly. The incoming "object_name" and "var_name" gives that unique name. */ template int checkpoint_map_stl(STL & in_map , std::string object_name , std::string var_name ) { unsigned int ii ; unsigned int cont_size ; char var_declare[128] ; typename STL::iterator iter ; int status ; typename STL::key_type * keys ; typename STL::mapped_type * items ; cont_size = in_map.size() ; std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); if ( cont_size > 0 ) { sprintf(var_declare, "%s %s_%s_keys[%d]" , abi::__cxa_demangle(typeid(*keys).name(), 0, 0, &status ), object_name.c_str(), var_name.c_str(), cont_size) ; keys = (typename STL::key_type *)TMM_declare_var_s(var_declare) ; //message_publish(1, "HERE with %s\n", var_declare) ; sprintf(var_declare, "%s %s_%s_data[%d]" , abi::__cxa_demangle(typeid(*items).name(), 0, 0, &status ), object_name.c_str(), var_name.c_str(), cont_size) ; items = (typename STL::mapped_type *)TMM_declare_var_s(var_declare) ; //message_publish(1, "HERE with %s\n", var_declare) ; /* copy the contents of the map the 2 arrays */ for ( iter = in_map.begin() , ii = 0 ; iter != in_map.end() ; iter++ , ii++ ) { keys[ii] = iter->first ; items[ii] = iter->second ; } } return 0 ; } template int checkpoint_stl(std::map & in_map , std::string object_name , std::string var_name ) { return checkpoint_map_stl( in_map , object_name , var_name ) ; } template int checkpoint_stl(std::multimap & in_map , std::string object_name , std::string var_name ) { return checkpoint_map_stl( in_map , object_name , var_name ) ; } template int checkpoint_map_stl_key_string(STL & in_map , std::string object_name , std::string var_name ) { unsigned int ii ; unsigned int cont_size ; char var_declare[128] ; typename STL::iterator iter ; int status ; char ** keys ; typename STL::mapped_type * items ; cont_size = in_map.size() ; std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); if ( cont_size > 0 ) { sprintf(var_declare, "char * %s_%s_keys[%d]" , object_name.c_str(), var_name.c_str() , cont_size) ; keys = (char **)TMM_declare_var_s(var_declare) ; //message_publish(1, "STRING KEY HERE with %s\n", var_declare) ; sprintf(var_declare, "%s %s_%s_data[%d]" , abi::__cxa_demangle(typeid(*items).name(), 0, 0, &status ), object_name.c_str(), var_name.c_str() , cont_size) ; items = (typename STL::mapped_type *)TMM_declare_var_s(var_declare) ; //message_publish(1, "STRING KEY HERE with %s\n", var_declare) ; /* copy the contents of the map the 2 arrays */ for ( iter = in_map.begin() , ii = 0 ; iter != in_map.end() ; iter++ , ii++ ) { keys[ii] = (char *)((iter->first).c_str()) ; items[ii] = iter->second ; } } return 0 ; } template int checkpoint_stl(std::map & in_map , std::string object_name , std::string var_name ) { return checkpoint_map_stl_key_string( in_map , object_name , var_name ) ; } template int checkpoint_stl(std::multimap & in_map , std::string object_name , std::string var_name ) { return checkpoint_map_stl_key_string( in_map , object_name , var_name ) ; } template int checkpoint_map_stl_data_string(STL & in_map , std::string object_name , std::string var_name ) { unsigned int ii ; unsigned int cont_size ; char var_declare[128] ; typename STL::iterator iter ; int status ; typename STL::key_type * keys ; char ** items ; cont_size = in_map.size() ; std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); if ( cont_size > 0 ) { sprintf(var_declare, "%s %s_%s_keys[%d]" , abi::__cxa_demangle(typeid(*keys).name(), 0, 0, &status ), object_name.c_str(), var_name.c_str() , cont_size) ; keys = (typename STL::key_type *)TMM_declare_var_s(var_declare) ; //message_publish(1, "STRING KEY HERE with %s\n", var_declare) ; sprintf(var_declare, "char * %s_%s_data[%d]" , object_name.c_str(), var_name.c_str() , cont_size) ; items = (char **)TMM_declare_var_s(var_declare) ; //message_publish(1, "STRING KEY HERE with %s\n", var_declare) ; /* copy the contents of the map the 2 arrays */ for ( iter = in_map.begin() , ii = 0 ; iter != in_map.end() ; iter++ , ii++ ) { keys[ii] = iter->first ; items[ii] = (char *)((iter->second).c_str()) ; } } return 0 ; } template int checkpoint_stl(std::map & in_map , std::string object_name , std::string var_name ) { return checkpoint_map_stl_data_string( in_map , object_name , var_name ) ; } template int checkpoint_stl(std::multimap & in_map , std::string object_name , std::string var_name ) { return checkpoint_map_stl_data_string( in_map , object_name , var_name ) ; } template int checkpoint_map_stl_strings(STL & in_map , std::string object_name , std::string var_name ) { unsigned int ii ; unsigned int cont_size ; char var_declare[128] ; typename STL::iterator iter ; char ** keys ; char ** items ; cont_size = in_map.size() ; std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); if ( cont_size > 0 ) { sprintf(var_declare, "char * %s_%s_keys[%d]" , object_name.c_str(), var_name.c_str() , cont_size) ; keys = (char **)TMM_declare_var_s(var_declare) ; //message_publish(1, "STRING KEY HERE with %s\n", var_declare) ; sprintf(var_declare, "char * %s_%s_data[%d]" , object_name.c_str(), var_name.c_str() , cont_size) ; items = (char **)TMM_declare_var_s(var_declare) ; //message_publish(1, "STRING KEY HERE with %s\n", var_declare) ; /* copy the contents of the map the 2 arrays */ for ( iter = in_map.begin() , ii = 0 ; iter != in_map.end() ; iter++ , ii++ ) { keys[ii] = (char *)((iter->first).c_str()) ; items[ii] = (char *)((iter->second).c_str()) ; } } return 0 ; } int checkpoint_stl(std::map & in_map , std::string object_name , std::string var_name ) ; int checkpoint_stl(std::multimap & in_map , std::string object_name , std::string var_name ) ; template int delete_map_stl(STL & in_map __attribute__ ((unused)), std::string object_name , std::string var_name ) { std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); REF2 * items_ref ; items_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_keys")).c_str()) ; if ( items_ref != NULL ) { TMM_delete_var_n((object_name + std::string("_") + var_name + std::string("_keys")).c_str() ) ; TMM_delete_var_n((object_name + std::string("_") + var_name + std::string("_data")).c_str() ) ; free(items_ref) ; } return 0 ; } template int delete_stl(std::map & in_map , std::string object_name , std::string var_name ) { return delete_map_stl(in_map , object_name , var_name) ; } template int delete_stl(std::multimap & in_map , std::string object_name , std::string var_name ) { return delete_map_stl(in_map , object_name , var_name) ; } /* For all restore_map_stl varieties. Find the arrays the map data was stored in the checkpoint using ref_attributes From the address of the resulting ref_attributes, we can figure out the number of items that were stored in the checkpoint. Knowing the size, we can restore the map from the 2 arrays. */ template int restore_map_stl(STL & in_map , std::string object_name , std::string var_name ) { unsigned int ii ; unsigned int cont_size ; REF2 * keys_ref , * items_ref ; typename STL::key_type * keys ; typename STL::mapped_type * items ; //message_publish(1, "in regular map template restore\n") ; in_map.clear() ; std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); keys_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_keys")).c_str()) ; items_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_data")).c_str()) ; if ( keys_ref != NULL && items_ref != NULL ) { keys = (typename STL::key_type *)keys_ref->address ; items = (typename STL::mapped_type *)items_ref->address ; cont_size = get_size((char *)keys) ; for ( ii = 0 ; ii < cont_size ; ii++ ) { in_map.insert( std::pair(keys[ii], items[ii])) ; } delete_stl( in_map , object_name , var_name ) ; } return 0 ; } template int restore_stl(std::map & in_map , std::string object_name , std::string var_name ) { return restore_map_stl(in_map , object_name , var_name) ; return 0 ; } template int restore_stl(std::multimap & in_map , std::string object_name , std::string var_name ) { return restore_map_stl(in_map , object_name , var_name) ; } template int restore_map_stl_key_string( STL & in_map , std::string object_name , std::string var_name ) { unsigned int ii ; unsigned int cont_size ; REF2 * keys_ref , * items_ref ; char ** keys ; typename STL::mapped_type * items ; in_map.clear() ; std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); keys_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_keys")).c_str()) ; items_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_data")).c_str()) ; if ( keys_ref != NULL && items_ref != NULL ) { keys = (char **)keys_ref->address ; items = (typename STL::mapped_type *)items_ref->address ; cont_size = get_size((char *)keys) ; for ( ii = 0 ; ii < cont_size ; ii++ ) { in_map.insert( std::pair(std::string(keys[ii]), items[ii])) ; } delete_stl( in_map , object_name , var_name ) ; } return 0 ; } template int restore_stl(std::map & in_map , std::string object_name , std::string var_name ) { return restore_map_stl_key_string(in_map , object_name , var_name) ; } template int restore_stl(std::multimap & in_map , std::string object_name , std::string var_name ) { return restore_map_stl_key_string(in_map , object_name , var_name) ; } template int restore_map_stl_data_string(STL & in_map , std::string object_name , std::string var_name ) { unsigned int ii ; unsigned int cont_size ; REF2 * keys_ref , * items_ref ; typename STL::key_type * keys ; char ** items ; //message_publish(1, "in specialized map template restore\n") ; in_map.clear() ; std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); keys_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_keys")).c_str()) ; items_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_data")).c_str()) ; if ( keys_ref != NULL && items_ref != NULL ) { keys = (typename STL::key_type *)keys_ref->address ; items = (char **)items_ref->address ; cont_size = get_size((char *)keys) ; for ( ii = 0 ; ii < cont_size ; ii++ ) { in_map.insert( std::pair(keys[ii] , std::string(items[ii]))) ; } delete_stl( in_map , object_name , var_name ) ; } return 0 ; } template int restore_stl(std::map & in_map , std::string object_name , std::string var_name ) { return restore_map_stl_data_string(in_map , object_name , var_name) ; } template int restore_stl(std::multimap & in_map , std::string object_name , std::string var_name ) { return restore_map_stl_data_string(in_map , object_name , var_name) ; } template int restore_map_stl_strings(STL & in_map , std::string object_name , std::string var_name ) { unsigned int ii ; unsigned int cont_size ; REF2 * keys_ref , * items_ref ; char ** keys ; char ** items ; //message_publish(1, "in specialized map template restore\n") ; /* Find the arrays the map data was stored in the checkpoint using ref_attributes From the address of the resulting ref_attributes, we can figure out the number of items that were stored in the checkpoint. Knowing the size, we can restore the map from the 2 arrays. This template only works for string map keys. */ in_map.clear() ; std::replace_if(object_name.begin(), object_name.end(), std::ptr_fun(&std::ispunct), '_'); keys_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_keys")).c_str()) ; items_ref = ref_attributes((char *)(object_name + std::string("_") + var_name + std::string("_data")).c_str()) ; if ( keys_ref != NULL && items_ref != NULL ) { keys = (char **)keys_ref->address ; items = (char **)items_ref->address ; cont_size = get_size((char *)keys) ; for ( ii = 0 ; ii < cont_size ; ii++ ) { in_map.insert( std::pair(std::string(keys[ii]) , std::string(items[ii]))) ; } delete_stl( in_map , object_name , var_name ) ; } return 0 ; } int restore_stl(std::map & in_map , std::string object_name , std::string var_name ) ; int restore_stl(std::multimap & in_map , std::string object_name , std::string var_name ) ; #endif #endif