/** * **************************************************************************** * Copyright (c) 2010-2016 by Min Cai (min.cai.china@gmail.com). * <p> * This file is part of the Archimulator multicore architectural simulator. * <p> * Archimulator is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * <p> * Archimulator is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * <p> * You should have received a copy of the GNU General Public License * along with Archimulator. If not, see <http://www.gnu.org/licenses/>. * **************************************************************************** */ package archimulator.uncore.coherence.msi.flow; import archimulator.isa.Memory; import archimulator.uncore.MemoryHierarchyAccess; import archimulator.uncore.coherence.msi.controller.Controller; import archimulator.util.Params; import archimulator.util.collection.tree.Node; import java.util.ArrayList; import java.util.List; /** * Cache coherence flow. * * @author Min Cai */ public abstract class CacheCoherenceFlow extends Params implements Node { private long id; private Controller generator; private CacheCoherenceFlow producerFlow; private CacheCoherenceFlow ancestorFlow; private List<CacheCoherenceFlow> childFlows; private int numPendingDescendantFlows; private long beginCycle; private long endCycle; private boolean completed; private MemoryHierarchyAccess access; private int tag; /** * Create a cache coherence flow. * * @param generator the generator controller * @param producerFlow the producer cache coherence flow * @param access the memory hierarchy access * @param tag the tag */ public CacheCoherenceFlow(Controller generator, CacheCoherenceFlow producerFlow, MemoryHierarchyAccess access, int tag) { this.id = generator.getSimulation().currentCacheCoherenceFlowId++; this.generator = generator; this.producerFlow = producerFlow; this.ancestorFlow = producerFlow == null ? this : producerFlow.ancestorFlow; this.childFlows = new ArrayList<>(); this.access = access; this.tag = tag; this.onCreate(); } /** * Act on when the cache coherence flow begins. */ private void onCreate() { this.beginCycle = this.generator.getCycleAccurateEventQueue().getCurrentCycle(); if (this.producerFlow == null) { this.generator.getSimulation().pendingFlows.add(this); } else { this.producerFlow.childFlows.add(this); } this.ancestorFlow.numPendingDescendantFlows++; } /** * Act on when the cache coherence flow is completed. */ public void onCompleted() { this.completed = true; this.endCycle = this.generator.getCycleAccurateEventQueue().getCurrentCycle(); this.ancestorFlow.numPendingDescendantFlows--; if (this.ancestorFlow.numPendingDescendantFlows == 0) { this.generator.getSimulation().pendingFlows.remove(this.ancestorFlow); } } /** * Get the ID of the cache coherence flow. * * @return the ID of the cache coherence flow */ public long getId() { return id; } /** * Get the ancestor cache coherence flow. * * @return the ancestor cache coherence flow */ public CacheCoherenceFlow getAncestorFlow() { return ancestorFlow; } /** * Get the producer cache coherence flow. * * @return the producer cache coherence flow */ public CacheCoherenceFlow getProducerFlow() { return producerFlow; } /** * Get the list of child flows. * * @return the list of child flows */ public List<CacheCoherenceFlow> getChildFlows() { return childFlows; } /** * Get the cycle when the cache coherence flow begins. * * @return the cycle when the cache coherence flow begins */ public long getBeginCycle() { return beginCycle; } /** * Get the cycle when the cache coherence flow is completed (ended). * * @return the cycle when the cache coherence flow is completed (ended) */ public long getEndCycle() { return endCycle; } /** * Get the generator controller. * * @return the generator controller */ public Controller getGenerator() { return generator; } /** * Get a value indicating whether the cache coherence flow is completed or not. * * @return a value indicating whether the cache coherence flow is completed or not */ public boolean isCompleted() { return completed; } /** * Get the memory hierarchy access. * * @return the memory hierarchy access */ public MemoryHierarchyAccess getAccess() { return access; } /** * Get the node value. * * @return the node value */ @Override public Object getValue() { return String.format("%s%s", this, this.completed ? " -> completed at " + endCycle : ""); } /** * Get the list of child flows. * * @return the list of child flows */ @Override public List<CacheCoherenceFlow> getChildren() { return this.childFlows; } /** * Get the tag. * * @return the tag */ public int getTag() { return tag; } /** * Get the data if meaningful. * * @return the data if meaningful */ public byte[] getData() { Memory memory = this.getAccess().getThread().getContext().getProcess().getMemory(); int lineSize = this.getAccess().getThread().getExperiment().getConfig().getL1DLineSize(); return memory.readBlock(this.getTag(), lineSize / 4); } }