예제 #1
0
 public virtual void FindAndLock(uint addr, bool isBlocking, bool isRead, bool isRetry, FindAndLockDelegate onCompletedCallback)
 {
     throw new NotImplementedException ();
 }
예제 #2
0
        public override void FindAndLock(uint addr, bool isBlocking, bool isRead, bool isRetry, FindAndLockDelegate onCompletedCallback)
        {
            uint @set, way, tag;
            MESIState state;

            bool hasHit = this.Cache.FindLine (addr, out @set, out way, out tag, out state, true);

            this.Stat.Accesses++;
            if (hasHit) {
                this.Stat.Hits++;
            }
            if (isRead) {
                this.Stat.Reads++;

                if (isBlocking) {
                    this.Stat.BlockingReads++;
                } else {
                    this.Stat.NonblockingReads++;
                }

                if (hasHit) {
                    this.Stat.ReadHits++;
                }
            } else {
                this.Stat.Writes++;

                if (isBlocking) {
                    this.Stat.BlockingWrites++;
                } else {
                    this.Stat.NonblockingWrites++;
                }

                if (hasHit) {
                    this.Stat.WriteHits++;
                }
            }

            if (!isRetry) {
                this.Stat.NoRetryAccesses++;

                if (hasHit) {
                    this.Stat.NoRetryHits++;
                }

                if (isRead) {
                    this.Stat.NoRetryReads++;

                    if (hasHit) {
                        this.Stat.NoRetryReadHits++;
                    }
                } else {
                    this.Stat.NoRetryWrites++;

                    if (hasHit) {
                        this.Stat.NoRetryWriteHits++;
                    }
                }
            }

            uint dumbTag;

            if (!hasHit) {
                way = this.Cache.FindVictimToEvict (@set);
                this.Cache.GetLine (@set, way, out dumbTag, out state);
            }

            DirectoryLock dirLock = this.Cache.Directory.Locks[(int)@set];
            if (!dirLock.Lock ()) {
                if (isBlocking) {
                    onCompletedCallback (true, @set, way, state, tag, dirLock);
                } else {
                    this.Retry (() => this.FindAndLock (addr, isBlocking, isRead, true, onCompletedCallback));
                }
            } else {
                this.Cache[@set][way].TransientTag = tag;

                if (!hasHit && state != MESIState.Invalid) {
                    this.Schedule (() => { this.Evict (@set, way, hasError =>{uint dumbTag1;if (!hasError) {this.Stat.Evictions++;this.Cache.GetLine (@set, way, out dumbTag1, out state);onCompletedCallback (false, @set, way, state, tag, dirLock);} else {this.Cache.GetLine (@set, way, out dumbTag, out state);dirLock.Unlock ();onCompletedCallback (true, @set, way, state, tag, dirLock);}}); }, this.HitLatency);
                } else {
                    this.Schedule (() => onCompletedCallback (false, @set, way, state, tag, dirLock), this.HitLatency);
                }
            }
        }