void SimulationSystem::Run( SystemContext* context ) { try{ m_context = context; InitializeResources(); context->executedCycles = 1; s64 numInsns = context->executionInsns; s64 numCycles = context->executionCycles; while(true){ context->globalClock->Tick(); for( int i = 0; i < context->threads.GetSize(); i++ ){ Thread* thread = context->threads[i]; g_dumper.SetCurrentInsnCount( thread, thread->GetCore()->GetRetirer()->GetNumRetiredInsns() ); g_dumper.SetCurrentCycle( thread, context->executedCycles ); } SimulateCycle(); bool exitSimulation = true; s64 retiredInsns = 0; for( int i = 0; i < context->cores.GetSize(); i++ ){ Core* core = context->cores[i]; if( !core->GetRetirer()->IsEndOfProgram() ){ // Next PC が 0 になる分岐命令がリタイアしていたら終了 exitSimulation = false; } retiredInsns += core->GetRetirer()->GetNumRetiredInsns(); } // 終了条件 if(exitSimulation){ break; } else if( numCycles > 0 ){ // 実行サイクル数を指定した場合 if( context->executedCycles >= numCycles ) break; } else{ // 実行命令数を指定した場合 if( retiredInsns >= numInsns ) break; } ++context->executedCycles; } // リタイアした命令数をupdate context->executedInsns.clear(); for( int i = 0; i < context->threads.GetSize(); i++ ){ context->executedInsns.push_back( context->threads[i]->GetInorderList()->GetRetiredInsns() ); } } catch( std::runtime_error& error ){ String msg; msg.format( "%s\n" "Last simulated cycle: %lld\n" , error.what(), m_context->executedCycles ); throw std::runtime_error( msg.c_str() ); } }