private void ReadRequestUpdown(CoherentCacheNode source, uint @set, uint way, uint tag, MESIState state, DirectoryLock dirLock, Action<bool, bool> onCompletedCallback) { uint pending = 1; if (state != MESIState.Invalid) { DirectoryEntry dirEntry = this.Cache.Directory.Entries[(int)@set][(int)way]; if (dirEntry.Owner != null && dirEntry.Owner != source) { pending++; this.ReadRequest (dirEntry.Owner, tag, (hasError, isShared) => this.ReadRequestUpdownFinish (source, @set, way, dirLock, ref pending, onCompletedCallback)); } this.ReadRequestUpdownFinish (source, @set, way, dirLock, ref pending, onCompletedCallback); } else { this.ReadRequest (this.Next, tag, (hasError, isShared) => { if (!hasError) { this.Cache.SetLine (@set, way, tag, isShared ? MESIState.Shared : MESIState.Exclusive); this.ReadRequestUpdownFinish (source, @set, way, dirLock, ref pending, onCompletedCallback); } else { dirLock.Unlock (); this.Schedule (() => onCompletedCallback (true, false), 2); } }); } }
private void WriteRequestUpdownFinish(CoherentCacheNode source, bool hasError, uint @set, uint way, uint tag, MESIState state, DirectoryLock dirLock, Action<bool> onCompletedCallback) { if (!hasError) { DirectoryEntry dirEntry = this.Cache.Directory.Entries[(int)@set][(int)way]; dirEntry.SetSharer (source); dirEntry.Owner = source; this.Cache.AccessLine (@set, way); if (state != MESIState.Modified) { this.Cache.SetLine (@set, way, tag, MESIState.Exclusive); } dirLock.Unlock (); this.Schedule (() => onCompletedCallback (false), 2); } else { dirLock.Unlock (); this.Schedule (() => onCompletedCallback (true), 2); } }
public static bool IsWriteHit(MESIState state) { return state == MESIState.Modified || state == MESIState.Exclusive; }
public static bool IsReadHit(MESIState state) { return state != MESIState.Invalid; }
public void SetLine(uint @set, uint way, uint tag, MESIState state) { Debug.Assert (@set >= 0 && @set < this.NumSets); Debug.Assert (way >= 0 && way < this.Associativity); this.AccessLine (@set, way); this[@set][way].Tag = tag; this[@set][way].State = state; }
public void GetLine(uint @set, uint way, out uint tag, out MESIState state) { Debug.Assert (@set >= 0 && @set < this.NumSets); Debug.Assert (way >= 0 && way < this.Associativity); tag = this[@set][way].Tag; state = this[@set][way].State; }
public bool FindLine(uint addr, out uint @set, out uint way, out uint tag, out MESIState state, bool checkTransientTag) { @set = addr.GetIndex (this.Geometry); tag = addr.GetTag (this.Geometry); CacheLine lineFound = this.GetLine (addr, checkTransientTag); way = lineFound != null ? lineFound.Way : 0; state = lineFound != null ? lineFound.State : MESIState.Invalid; return lineFound != null; }