00001 // 00002 // Copyright (c) 2005-2008 Kenichi Watanabe. 00003 // Copyright (c) 2005-2008 Yasuhiro Watari. 00004 // Copyright (c) 2005-2008 Hironori Ichibayashi. 00005 // Copyright (c) 2008-2009 Kazuo Horio. 00006 // Copyright (c) 2009-2013 Naruki Kurata. 00007 // Copyright (c) 2005-2013 Ryota Shioya. 00008 // Copyright (c) 2005-2013 Masahiro Goshima. 00009 // 00010 // This software is provided 'as-is', without any express or implied 00011 // warranty. In no event will the authors be held liable for any damages 00012 // arising from the use of this software. 00013 // 00014 // Permission is granted to anyone to use this software for any purpose, 00015 // including commercial applications, and to alter it and redistribute it 00016 // freely, subject to the following restrictions: 00017 // 00018 // 1. The origin of this software must not be misrepresented; you must not 00019 // claim that you wrote the original software. If you use this software 00020 // in a product, an acknowledgment in the product documentation would be 00021 // appreciated but is not required. 00022 // 00023 // 2. Altered source versions must be plainly marked as such, and must not be 00024 // misrepresented as being the original software. 00025 // 00026 // 3. This notice may not be removed or altered from any source 00027 // distribution. 00028 // 00029 // 00030 00031 00032 #include <pch.h> 00033 00034 #include "Sim/Foundation/Checkpoint/CheckpointMaster.h" 00035 00036 #include "Sim/Foundation/Checkpoint/CheckpointedData.h" 00037 #include "Utility/RuntimeError.h" 00038 #include "Sim/Core/Core.h" 00039 #include "Sim/Core/DataPredTypes.h" 00040 00041 00042 using namespace std; 00043 using namespace Onikiri; 00044 00045 CheckpointMaster::CheckpointMaster() : 00046 m_capacity(0) 00047 { 00048 } 00049 00050 CheckpointMaster::~CheckpointMaster() 00051 { 00052 // Release all checkpoints and related data. 00053 for( CheckpointListIterator i = m_checkpoint.begin(); i != m_checkpoint.end(); ++i ){ 00054 DestroyCheckpoint( *i ); 00055 } 00056 m_checkpoint.clear(); 00057 00058 ReleaseParam(); 00059 } 00060 00061 void CheckpointMaster::Initialize( InitPhase phase ) 00062 { 00063 if( phase == INIT_PRE_CONNECTION ){ 00064 LoadParam(); 00065 m_dataTable.resize( SLOT_MAX ); 00066 } 00067 00068 } 00069 00070 // Register check pointed data. 00071 // This method must be called from CheckpointedData::Initialize(). 00072 CheckpointedDataHandle CheckpointMaster::Register( 00073 CheckpointedDataBase* data, 00074 Slot slot 00075 ){ 00076 m_data.push_back( data ); 00077 m_dataTable[ slot ].push_back( data ); 00078 return m_data.size() - 1; 00079 } 00080 00081 // Create a new checkpoint. 00082 // Returns the pointer of a checkpoint that identifies a generation of check-pointed data. 00083 Checkpoint* CheckpointMaster::CreateCheckpoint() 00084 { 00085 ASSERT( m_capacity > m_checkpoint.size(), "cannot create checkpoint." ); 00086 00087 Checkpoint* cp = ConstructCheckpoint( m_data.size() ); 00088 m_checkpoint.push_back( cp ); 00089 00090 for( CheckpointedDataListType::iterator i = m_data.begin(); i != m_data.end(); ++i ){ 00091 (*i)->Allocate( cp ); 00092 } 00093 return cp; 00094 } 00095 00096 // Current data is becked up to 'checkpoint'. 00097 void CheckpointMaster::Backup( Checkpoint* checkpoint, Slot slot ) 00098 { 00099 ASSERT( checkpoint != NULL ); 00100 CheckpointedDataListType* copyTo = &m_dataTable[ slot ]; 00101 for( CheckpointedDataListType::iterator i = copyTo->begin(); i != copyTo->end(); ++i ){ 00102 (*i)->Backup( checkpoint ); 00103 } 00104 } 00105 00106 // Commits 'checkpoint'. 00107 // Ops backs up states are committed and their checkpoints are released. 00108 void CheckpointMaster::Commit( Checkpoint* checkpoint ) 00109 { 00110 ASSERT( 00111 m_checkpoint.size() > 0 && m_checkpoint.front() == checkpoint, 00112 "A checkpoint that is not at the front is committed. Checkpoints must be flushed in-order." 00113 ); 00114 DestroyCheckpoint( checkpoint ); 00115 m_checkpoint.pop_front(); 00116 } 00117 00118 // Flushes 'checkpoint'. 00119 void CheckpointMaster::Flush( Checkpoint* checkpoint ) 00120 { 00121 ASSERT( 00122 m_checkpoint.size() > 0 && m_checkpoint.back() == checkpoint, 00123 "A checkpoint that is not at the back is flushed. Checkpoints must be flushed from the back." 00124 ); 00125 DestroyCheckpoint( checkpoint ); 00126 m_checkpoint.pop_back(); 00127 } 00128 00129 // Recover current data to check-pointed data of 'checkpoint'. 00130 void CheckpointMaster::Recover( Checkpoint* checkpoint ) 00131 { 00132 for( CheckpointedDataListType::iterator i = m_data.begin(); i != m_data.end(); ++i ){ 00133 (*i)->Recover( checkpoint ); 00134 } 00135 } 00136 00137 // Methods for an object pool of checkpoints. 00138 Checkpoint* CheckpointMaster::ConstructCheckpoint( size_t refSize ) 00139 { 00140 Checkpoint* ptr = m_checkpointPool.construct( m_data.size() ); 00141 ASSERT( ptr != NULL, "Memory allocation failed." ); 00142 return ptr; 00143 } 00144 00145 void CheckpointMaster::DestroyCheckpoint( Checkpoint* checkpoint ) 00146 { 00147 // Erase data referred from checkpoint. 00148 for( CheckpointedDataListType::iterator i = m_data.begin(); i != m_data.end(); ++i ){ 00149 (*i)->Erase( checkpoint ); 00150 } 00151 00152 m_checkpointPool.destroy( checkpoint ); 00153 }