public void putBus_toUse(int pID, CacheAccessResult result, MESI_States pS, bool used = false) { if (this.waitingProcessors.Count == 0) //First entry into the queue else the bus would already be in use. { this.useCycles = 0; this.inUse = true; } blockingInfo temp; temp.processorId = pID; temp.processorState = pS; temp.result = result; this.waitingProcessors.Enqueue(temp); }
private void snoopBus(int sendingProcessorId) { int slot = convertBinarytoDecimal(slotAddress); bool sharedSignal = false; int processorSupplyingData = -1; BusSignals servingSignal = bus.pendingSignal.Peek(); #region otherProcessorsSnooping foreach (var processor in processors) //each processor snoops the bus { if (processor.L1.blocks[slot].tag != tagAddress || processor.processorId == sendingProcessorId) //The processor does not have that data and do not process the signal on the sending processor. { continue; } else { MESI_States ownState = processor.L1.blocks[slot].currentState; switch (servingSignal) { case BusSignals.BusRd: switch (ownState) { case MESI_States.Modified: //flush data to memory flushData(); processor.L1.blocks[slot].currentState = MESI_States.Shared; sharedSignal = true; processorSupplyingData = processor.processorId; break; case MESI_States.Exclusive: processor.L1.blocks[slot].currentState = MESI_States.Shared; sharedSignal = true; processorSupplyingData = processor.processorId; break; case MESI_States.Shared: //do nothing. let it be at shared sharedSignal = true; processorSupplyingData = processor.processorId; break; case MESI_States.Invalid: //do nothing. break; default: break; } break; case BusSignals.BusRdX: switch (ownState) { case MESI_States.Modified: flushData(); processor.L1.blocks[slot].currentState = MESI_States.Invalid; processorSupplyingData = processor.processorId; break; case MESI_States.Exclusive: processor.L1.blocks[slot].currentState = MESI_States.Invalid; processorSupplyingData = processor.processorId; break; case MESI_States.Shared: processor.L1.blocks[slot].currentState = MESI_States.Invalid; processorSupplyingData = processor.processorId; break; case MESI_States.Invalid: //do nothing. break; default: break; } break; case BusSignals.BusInvalidate: switch (ownState) { case MESI_States.Modified: //not possible. Only the sending processor can have modified data. break; case MESI_States.Exclusive: processor.L1.blocks[slot].currentState = MESI_States.Invalid; break; case MESI_States.Shared: processor.L1.blocks[slot].currentState = MESI_States.Invalid; break; case MESI_States.Invalid: //do nothing. break; default: break; } break; case BusSignals.NoSignal: //do nothing. break; default: break; } } } #endregion #region respondingToResponse //update the sending processor's state. switch (servingSignal) { case BusSignals.BusRd: //the processor did not have the data. It will go into Exclusive or Shared state depending on if the shared signal was raised. if (sharedSignal == true) { processors[sendingProcessorId].L1.blocks[slot].currentState = MESI_States.Shared; //store data processors[sendingProcessorId].L1.blocks[slot].tag = processors[processorSupplyingData].L1.blocks[slot].tag; } else { processors[sendingProcessorId].L1.blocks[slot].currentState = MESI_States.Exclusive; //store data processors[sendingProcessorId].L1.blocks[slot].tag = tagAddress; } break; case BusSignals.BusRdX: //It will have modified (dirty) data coz it is asking for data with intent to modify processors[sendingProcessorId].L1.blocks[slot].currentState = MESI_States.Modified; if (processorSupplyingData != -1) //if some processor had this data //store data { processors[sendingProcessorId].L1.blocks[slot].tag = processors[processorSupplyingData].L1.blocks[slot].tag; } else { //store data processors[sendingProcessorId].L1.blocks[slot].tag = tagAddress; } break; case BusSignals.BusInvalidate: //It is about to modify its own copy. processors[sendingProcessorId].L1.blocks[slot].currentState = MESI_States.Modified; break; case BusSignals.NoSignal: break; default: break; } #endregion bus.pendingSignal.Dequeue(); //Signal has been served. }