bool CommonMigrator::RequestComplete( NVMainRequest *request ) { if( NVMTypeMatches(NVMain) && GetCurrentHookType( ) == NVMHOOK_PREISSUE ) { /* Ensure the Migrator translator is used. */ Migrator *migratorTranslator = dynamic_cast<Migrator *>(parent->GetTrampoline( )->GetDecoder( )); assert( migratorTranslator != NULL ); if( request->owner == parent->GetTrampoline( ) && request->tag == MIG_READ_TAG ) { /* A migration read completed, update state. */ migratorTranslator->SetMigrationState( request->address, MIGRATION_BUFFERED ); /* If both requests are buffered, we can attempt to write. */ bool bufferComplete = false; if( (request == promoRequest && migratorTranslator->IsBuffered( demotee )) || (request == demoRequest && migratorTranslator->IsBuffered( promotee )) ) { bufferComplete = true; } /* Make a new request to issue for write. Parent will delete current pointer. */ if( request == promoRequest ) { promoRequest = new NVMainRequest( ); *promoRequest = *request; } else if( request == demoRequest ) { demoRequest = new NVMainRequest( ); *demoRequest = *request; } else { assert( false ); } /* Swap the address and set type to write. */ if( bufferComplete ) { /* * Note: once IssueCommand is called, this hook may receive * a different parent, but fail the NVMTypeMatch check. As a * result we need to save a pointer to the NVMain class we * are issuing requests to. */ NVMObject *savedParent = parent->GetTrampoline( ); NVMAddress tempAddress = promoRequest->address; promoRequest->address = demoRequest->address; demoRequest->address = tempAddress; demoRequest->type = WRITE; promoRequest->type = WRITE; demoRequest->tag = MIG_WRITE_TAG; promoRequest->tag = MIG_WRITE_TAG; /* Try to issue these now, otherwise we can try later. */ bool demoIssued, promoIssued; demoIssued = savedParent->GetChild( demoRequest )->IssueCommand( demoRequest ); promoIssued = savedParent->GetChild( promoRequest )->IssueCommand( promoRequest ); if( demoIssued ) { migratorTranslator->SetMigrationState( demoRequest->address, MIGRATION_WRITING ); } if( promoIssued ) { migratorTranslator->SetMigrationState( promoRequest->address, MIGRATION_WRITING ); } promoBuffered = !promoIssued; demoBuffered = !demoIssued; } } /* A write completed. */ else if( request->owner == parent->GetTrampoline( ) && request->tag == MIG_WRITE_TAG ) { // Note: request should be deleted by parent migratorTranslator->SetMigrationState( request->address, MIGRATION_DONE ); migrationCount++; migration_cycles_ += GetEventQueue()->GetCurrentCycle() - begin_cycle_; } /* Some other request completed, see if we can ninja issue some migration writes that did not queue. */ else if( promoBuffered || demoBuffered ) { bool demoIssued, promoIssued; if( promoBuffered ) { promoIssued = parent->GetTrampoline( )->GetChild( promoRequest )->IssueCommand( promoRequest ); promoBuffered = !promoIssued; } if( demoBuffered ) { demoIssued = parent->GetTrampoline( )->GetChild( demoRequest )->IssueCommand( demoRequest ); demoBuffered = !demoIssued; } } } return true; }
bool MultiQueueMigrator::RequestComplete( NVMainRequest *request ) { // std::cout<<"\nMultiQueueMigrator ----- RequestComplete: "<<std::hex // <<request->address.GetPhysicalAddress()<<" FFFFFFFF\n"<<std::endl; if( NVMTypeMatches(NVMain) && GetCurrentHookType( ) == NVMHOOK_PREISSUE ) { // std::cout<<"\nRequestComplete: If? --- Yes! FFFFFFFF \n "<<std::endl; /* Ensure the Migrator translator is used. */ MQMigrator *migratorTranslator = dynamic_cast<MQMigrator *>(parent->GetTrampoline( )->GetDecoder( )); assert( migratorTranslator != NULL ); if( request->owner == parent->GetTrampoline( ) && request->tag == MIG_READ_TAG ) { /* A migration read completed, update state. */ //std::cout<<"set migration state to MQ_MIGRATION_BUFFERED"<<std::endl; migratorTranslator->SetMigrationState( request->address, MQ_MIGRATION_BUFFERED ); /* If both requests are buffered, we can attempt to write. */ bool bufferComplete = false; if( (request == promoRequest && migratorTranslator->IsBuffered( demotee )) || (request == demoRequest && migratorTranslator->IsBuffered( promotee )) ) { bufferComplete = true; } /* Make a new request to issue for write. Parent will delete current pointer. */ if( request == promoRequest ) { promoRequest = new NVMainRequest( ); *promoRequest = *request; } else if( request == demoRequest ) { demoRequest = new NVMainRequest( ); *demoRequest = *request; } else { assert( false ); } /* Swap the address and set type to write. */ if( bufferComplete ) { /* * Note: once IssueCommand is called, this hook may receive * a different parent, but fail the NVMTypeMatch check. As a * result we need to save a pointer to the NVMain class we * are issuing requests to. */ // std::cout<<"\nBoth_Buffer_Complete == true. FFFFFFFF\n"<<std::endl; NVMObject *savedParent = parent->GetTrampoline( ); NVMAddress tempAddress = promoRequest->address; promoRequest->address = demoRequest->address; demoRequest->address = tempAddress; demoRequest->type = WRITE; promoRequest->type = WRITE; demoRequest->tag = MIG_WRITE_TAG; promoRequest->tag = MIG_WRITE_TAG; /* Try to issue these now, otherwise we can try later. */ bool demoIssued, promoIssued; demoIssued = savedParent->GetChild( demoRequest )->IssueCommand( demoRequest ); promoIssued = savedParent->GetChild( promoRequest )->IssueCommand( promoRequest ); if( demoIssued ) { //std::cout<<"set migration state to MQ_MIGRATION_WRITING"<<std::endl; migratorTranslator->SetMigrationState( demoRequest->address, MQ_MIGRATION_WRITING ); } if( promoIssued ) { // std::cout<<"\npromo_Mig_Write Issued: "<<std::hex // <<promoRequest->address.GetPhysicalAddress()<<"\n"<<std::endl; //std::cout<<"set migration state to MQ_MIGRATION_WRITING"<<std::endl; migratorTranslator->SetMigrationState( promoRequest->address, MQ_MIGRATION_WRITING ); } promoBuffered = !promoIssued; demoBuffered = !demoIssued; } } /* A write completed. */ else if( request->owner == parent->GetTrampoline( ) && request->tag == MIG_WRITE_TAG ) { // Note: request should be deleted by parent //std::cout<<"set migration state to MQ_MIGRATION_DONE"<<std::endl; migratorTranslator->SetMigrationState( request->address, MQ_MIGRATION_DONE ); if( request == promoRequest ) { // std::cout<<"\n###### promo_Mig_Done. FFFFFFFF\n"<<std::endl; } else if( request == demoRequest ) { // std::cout<<"\n###### demo_Mig_Done. FFFFFFFF\n"<<std::endl; } migrationCount++; if( (request == promoRequest && migratorTranslator->IsMigrated( demotee )) || (request == demoRequest && migratorTranslator->IsMigrated( promotee )) ) { // std::cout<<"\nBoth migrations are done.\n"<<std::endl; } } /* Some other request completed, see if we can ninja issue some migration writes that did not queue. */ else if( promoBuffered || demoBuffered ) { bool demoIssued, promoIssued; if( promoBuffered ) { promoIssued = parent->GetTrampoline( )->GetChild( promoRequest )->IssueCommand( promoRequest ); promoBuffered = !promoIssued; } if( demoBuffered ) { demoIssued = parent->GetTrampoline( )->GetChild( demoRequest )->IssueCommand( demoRequest ); demoBuffered = !demoIssued; } } } return true; }