mirror of
https://github.com/nasa/trick.git
synced 2025-05-30 06:04:29 +00:00
Merge pull request #1349 from nasa/Issue_1348
Make MemoryManager::reset_memory and class destructors coordinate the…
This commit is contained in:
commit
8867baf1f8
@ -9,6 +9,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -683,6 +684,8 @@ namespace Trick {
|
|||||||
|
|
||||||
std::vector<ALLOC_INFO*> dependencies; /**< ** list of allocations used in a checkpoint. */
|
std::vector<ALLOC_INFO*> dependencies; /**< ** list of allocations used in a checkpoint. */
|
||||||
std::vector<ALLOC_INFO*> stl_dependencies; /**< ** list of allocations known to be STL checkpoint allocations */
|
std::vector<ALLOC_INFO*> stl_dependencies; /**< ** list of allocations known to be STL checkpoint allocations */
|
||||||
|
bool resetting_memory;
|
||||||
|
std::list<void*> deleted_addr_list; /**< ** list of addresses that have been deleted during reset_memory(). */
|
||||||
|
|
||||||
void execute_checkpoint( std::ostream& out_s );
|
void execute_checkpoint( std::ostream& out_s );
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ Trick::MemoryManager::MemoryManager()
|
|||||||
debug_level = 0;
|
debug_level = 0;
|
||||||
hexfloat_checkpoint = 0;
|
hexfloat_checkpoint = 0;
|
||||||
reduced_checkpoint = 1;
|
reduced_checkpoint = 1;
|
||||||
|
resetting_memory = false;
|
||||||
expanded_arrays = 0;
|
expanded_arrays = 0;
|
||||||
// start counter at 100mil. This (hopefully) ensures all alloc'ed ids are after external variables.
|
// start counter at 100mil. This (hopefully) ensures all alloc'ed ids are after external variables.
|
||||||
alloc_info_map_counter = 100000000 ;
|
alloc_info_map_counter = 100000000 ;
|
||||||
|
@ -295,6 +295,11 @@ void Trick::MemoryManager::reset_memory() {
|
|||||||
std::vector<void*> deletion_list;
|
std::vector<void*> deletion_list;
|
||||||
int ii, n_addrs;
|
int ii, n_addrs;
|
||||||
|
|
||||||
|
// Clear the deleted_addr_list at the start of reset memory. As delete_var() is called,
|
||||||
|
// and resetting_memory == true, the deleted address will be added to the deleted_addr_list.
|
||||||
|
resetting_memory = true;
|
||||||
|
deleted_addr_list.clear();
|
||||||
|
|
||||||
pthread_mutex_lock(&mm_mutex);
|
pthread_mutex_lock(&mm_mutex);
|
||||||
for (pos=alloc_info_map.begin() ; pos!=alloc_info_map.end() ; pos++ ) {
|
for (pos=alloc_info_map.begin() ; pos!=alloc_info_map.end() ; pos++ ) {
|
||||||
alloc_info = pos->second;
|
alloc_info = pos->second;
|
||||||
@ -310,6 +315,9 @@ void Trick::MemoryManager::reset_memory() {
|
|||||||
delete_var( deletion_list[ii]);
|
delete_var( deletion_list[ii]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetting_memory = false;
|
||||||
|
deleted_addr_list.clear();
|
||||||
|
|
||||||
// reset counter to 100mil. This (hopefully) ensures all alloc'ed ids are after external variables.
|
// reset counter to 100mil. This (hopefully) ensures all alloc'ed ids are after external variables.
|
||||||
alloc_info_map_counter = 100000000 ;
|
alloc_info_map_counter = 100000000 ;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include "trick/MemoryManager.hh"
|
#include "trick/MemoryManager.hh"
|
||||||
|
|
||||||
@ -38,6 +39,14 @@ int Trick::MemoryManager::delete_var(void* address ) {
|
|||||||
if ( alloc_info->stcl == TRICK_LOCAL ) {
|
if ( alloc_info->stcl == TRICK_LOCAL ) {
|
||||||
if ( alloc_info->alloc_type == TRICK_ALLOC_MALLOC ) {
|
if ( alloc_info->alloc_type == TRICK_ALLOC_MALLOC ) {
|
||||||
io_src_destruct_class( alloc_info );
|
io_src_destruct_class( alloc_info );
|
||||||
|
|
||||||
|
// The destructor that we just called MAY have deleted addresses
|
||||||
|
// that are already planned for deletion, say during reset_memory.
|
||||||
|
// So, keep a record of what we've recently deleted so we don't
|
||||||
|
// to warn that we can't find it, when reset_memory also tries to
|
||||||
|
// delete that same address.
|
||||||
|
deleted_addr_list.push_back(address);
|
||||||
|
|
||||||
free( address);
|
free( address);
|
||||||
} else if ( alloc_info->alloc_type == TRICK_ALLOC_NEW ) {
|
} else if ( alloc_info->alloc_type == TRICK_ALLOC_NEW ) {
|
||||||
io_src_delete_class( alloc_info );
|
io_src_delete_class( alloc_info );
|
||||||
@ -63,11 +72,34 @@ int Trick::MemoryManager::delete_var(void* address ) {
|
|||||||
// Delete the alloc_info record.
|
// Delete the alloc_info record.
|
||||||
free(alloc_info);
|
free(alloc_info);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// The allocation (address) we're tring to delete may have just been
|
||||||
|
// deleted by a user's destructor (using delete_var). Check the deleted_addr_list
|
||||||
|
// to see if the allocation was just deleted. If it was, then there's no
|
||||||
|
// problem. If it wasn't, then the MemoryManager never knew about it, and
|
||||||
|
// this call to delete_var() is a problem.
|
||||||
|
|
||||||
|
if ( resetting_memory == true) {
|
||||||
|
// Check the deleted_addr_list to see whether we recently deleted this address.
|
||||||
|
std::list<void*>::iterator iter =
|
||||||
|
std::find( deleted_addr_list.begin(), deleted_addr_list.end(), address );
|
||||||
|
// If we didn't recently delete it, then there's a problem.
|
||||||
|
if ( iter == deleted_addr_list.end() ) {
|
||||||
|
std::stringstream message;
|
||||||
|
message << "The MemoryManager cannot delete memory at address ["
|
||||||
|
<< address << "] because it has no record of it. Furthermore,"
|
||||||
|
<< " the MemoryManager has not recently deleted it while"
|
||||||
|
<< " resetting memory for a checkpoint reload.";
|
||||||
|
emitWarning(message.str());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
std::stringstream message;
|
std::stringstream message;
|
||||||
message << "The MemoryManager cannot delete memory at address ["
|
message << "The MemoryManager cannot delete memory at address ["
|
||||||
<< address << "] because it has no record of it.";
|
<< address << "] because it has no record of it.";
|
||||||
emitWarning(message.str());
|
emitWarning(message.str());
|
||||||
|
}
|
||||||
|
|
||||||
return 1 ;
|
return 1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ int Trick::MemoryManager::read_checkpoint( std::istream *is, bool do_restore_stl
|
|||||||
emitError("Checkpoint restore failed.") ;
|
emitError("Checkpoint restore failed.") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Search for stls and restore them
|
// Search for stls and restore them
|
||||||
if(do_restore_stls) {
|
if(do_restore_stls) {
|
||||||
for ( pos=alloc_info_map.begin() ; pos!=alloc_info_map.end() ; pos++ ) {
|
for ( pos=alloc_info_map.begin() ; pos!=alloc_info_map.end() ; pos++ ) {
|
||||||
@ -102,6 +103,11 @@ int Trick::MemoryManager::init_from_checkpoint( std::istream *is) {
|
|||||||
|
|
||||||
reset_memory();
|
reset_memory();
|
||||||
|
|
||||||
|
if (debug_level) {
|
||||||
|
std::cout << std::endl << "- Reading checkpoint." << std::endl;
|
||||||
|
std::cout.flush();
|
||||||
|
}
|
||||||
|
|
||||||
read_checkpoint( is);
|
read_checkpoint( is);
|
||||||
|
|
||||||
if (debug_level) {
|
if (debug_level) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user