00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <pch.h>
00033
00034 #include "Sim/Dumper/Dumper.h"
00035
00036 #include "Utility/RuntimeError.h"
00037 #include "Sim/Dumper/TraceDumper.h"
00038 #include "Sim/Dumper/VisualizationDumper.h"
00039 #include "Sim/Dumper/CountDumper.h"
00040 #include "Sim/Op/Op.h"
00041 #include "Sim/Core/Core.h"
00042
00043 namespace Onikiri
00044 {
00045 Dumper g_dumper;
00046 }
00047
00048 using namespace std;
00049 using namespace Onikiri;
00050
00051 Dumper::Dumper()
00052 {
00053 m_dumpEnabled = false;
00054 }
00055
00056 Dumper::~Dumper()
00057 {
00058 ReleaseDumper();
00059 }
00060
00061
00062 void Dumper::CreateThreadDumper(
00063 ThreadDumper* threadDumper,
00064 const String& suffix,
00065 PhysicalResourceArray<Core>& coreList
00066 ){
00067 ThreadDumper newDumper =
00068 {
00069 new TraceDumper(),
00070 new VisualizationDumper(),
00071 new CountDumper()
00072 };
00073 *threadDumper = newDumper;
00074
00075 threadDumper->traceDumper->Initialize( suffix );
00076 threadDumper->visDumper->Initialize( suffix, coreList );
00077 threadDumper->countDumper->Initialize( suffix );
00078
00079 m_dumpEnabled =
00080 threadDumper->traceDumper->Enabled() ||
00081 threadDumper->visDumper->IsEnabled() ||
00082 threadDumper->countDumper->Enabled() ||
00083 m_dumpEnabled;
00084 m_dumperList.push_back( *threadDumper );
00085 }
00086
00087
00088 void Dumper::Initialize(
00089 PhysicalResourceArray<Core>& coreList,
00090 PhysicalResourceArray<Thread>& threadList
00091 ){
00092 LoadParam();
00093
00094 m_dumpEnabled = false;
00095
00096 if( m_dumpEachThread ){
00097 for( int i = 0; i < threadList.GetSize(); i++ ){
00098 Thread* thread = threadList[i];
00099 ThreadDumper dumper;
00100 String suffix = "t" + boost::lexical_cast<String>(i);
00101 CreateThreadDumper( &dumper, suffix, coreList );
00102 m_dumperMap[thread] = dumper;
00103 }
00104 }
00105 else if( m_dumpEachCore ){
00106 for( int i = 0; i < coreList.GetSize(); i++ ){
00107 Core* core = coreList[i];
00108
00109 ThreadDumper dumper;
00110 String suffix = "c" + boost::lexical_cast<String>(i);
00111 CreateThreadDumper( &dumper, suffix, coreList );
00112
00113 for( int j = 0; j < core->GetThreadCount(); j++ ){
00114 Thread* thread = core->GetThread(j);
00115 m_dumperMap[thread] = dumper;
00116 }
00117 }
00118 }
00119 else{
00120 ThreadDumper dumper;
00121 CreateThreadDumper( &dumper, "", coreList );
00122 for( int i = 0; i < threadList.GetSize(); i++ ){
00123 Thread* thread = threadList[i];
00124 m_dumperMap[thread] = dumper;
00125 }
00126 }
00127 }
00128
00129 template <class T> static void DeleteDumper(T*& ptr)
00130 {
00131 if(ptr){
00132 delete ptr;
00133 ptr = NULL;
00134 }
00135 }
00136
00137 void Dumper::Finalize()
00138 {
00139 for( DumperList::iterator i = m_dumperList.begin();
00140 i != m_dumperList.end();
00141 ++i
00142 ){
00143 i->traceDumper->Finalize();
00144 i->visDumper->Finalize();
00145 i->countDumper->Finalize();
00146 }
00147 ReleaseDumper();
00148 ReleaseParam();
00149 }
00150
00151 void Dumper::ReleaseDumper()
00152 {
00153 for( DumperList::iterator i = m_dumperList.begin();
00154 i != m_dumperList.end();
00155 ++i
00156 ){
00157 DeleteDumper( i->traceDumper );
00158 DeleteDumper( i->visDumper );
00159 DeleteDumper( i->countDumper );
00160 }
00161
00162 m_dumperList.clear();
00163 m_dumperMap.clear();
00164 }
00165
00166
00167 void Dumper::DumpStallBeginImpl(OpIterator op)
00168 {
00169 Thread* thread = op->GetThread();
00170 ThreadDumper& dumper = m_dumperMap[thread];
00171
00172 dumper.traceDumper->DumpStallBegin(&*op);
00173 dumper.visDumper->PrintStallBegin(op);
00174 }
00175
00176 void Dumper::DumpStallEndImpl(OpIterator op)
00177 {
00178 Thread* thread = op->GetThread();
00179 ThreadDumper& dumper = m_dumperMap[thread];
00180
00181 dumper.traceDumper->DumpStallEnd(&*op);
00182 dumper.visDumper->PrintStallEnd(op);
00183 }
00184
00185 void Dumper::DumpImpl(DUMP_STATE state, OpIterator op, int detail)
00186 {
00187 if(!m_dumpEnabled)
00188 return;
00189
00190 Thread* thread = op->GetThread();
00191 ThreadDumper& dumper = m_dumperMap[thread];
00192
00193 dumper.traceDumper->Dump(state, &*op, detail);
00194 dumper.visDumper->PrintOpState(op, state);
00195 }
00196
00197 void Dumper::SetCurrentCycleImpl( Thread* thread, s64 cycle )
00198 {
00199 if(!m_dumpEnabled)
00200 return;
00201
00202 ThreadDumper& dumper = m_dumperMap[thread];
00203 dumper.traceDumper->SetCurrentCycle(cycle);
00204 dumper.visDumper->SetCurrentCycle(cycle);
00205 dumper.countDumper->SetCurrentCycle(cycle);
00206 }
00207
00208 void Dumper::SetCurrentInsnCountImpl( Thread* thread, s64 count )
00209 {
00210 if(!m_dumpEnabled)
00211 return;
00212
00213 ThreadDumper& dumper = m_dumperMap[thread];
00214 dumper.countDumper->SetCurrentInsnCount(count);
00215 dumper.visDumper->SetCurrentInsnCount(thread,count);
00216 }
00217
00218 void Dumper::DumpOpDependencyImpl(
00219 const OpIterator producerOp, const OpIterator consumerOp, DumpDependency type )
00220 {
00221 if(!m_dumpEnabled)
00222 return;
00223
00224 Thread* thread = producerOp->GetThread();
00225 ThreadDumper& dumper = m_dumperMap[thread];
00226 dumper.visDumper->PrintOpDependency( producerOp, consumerOp, type );
00227 }
00228
00229 void Dumper::DumpRawStageImpl( OpIterator op, bool begin, const char*stage, DumpLane lane )
00230 {
00231 if(!m_dumpEnabled)
00232 return;
00233
00234 ASSERT( !op.IsNull(), "A null op is passed." );
00235 Thread* thread = op->GetThread();
00236 ThreadDumper& dumper = m_dumperMap[thread];
00237 dumper.visDumper->PrintRawOutput( op, begin, stage, lane );
00238 }
00239 void Dumper::SetEnabledImpl( bool enabled )
00240 {
00241 m_dumpEnabled = enabled;
00242 }
00243
00244