blob: 37383dd29be0853ade7b96eaca3a0feb4ca330b0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.analysis.os.linux.core.execution.graph;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.os.linux.core.model.HostThread;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
/**
* This class contains the model of a Linux system
*
* TODO: This model is custom made for the LTTng dependency analysis for ease of
* development of the feature, but most of it and the classes it uses also apply
* to any Linux OS trace, so the classes in this package should be moved to
* analysis.os.linux
*
* @author Francis Giraldeau
* @author Geneviève Bastien
* @since 2.4
*/
public class OsSystemModel {
private final Table<String, Integer, HostThread> fCurrentTids = HashBasedTable.create();
private final Table<String, Integer, Deque<OsInterruptContext>> fIntCtxStacks = HashBasedTable.create();
private final Map<HostThread, OsWorker> fWorkerMap = new HashMap<>();
/**
* Cache the TID currently on the CPU of a host, for easier access later on
*
* @param cpu
* The CPU ID
* @param ht
* The {@link HostThread} object that is running on this CPU
*/
public void cacheTidOnCpu(Integer cpu, HostThread ht) {
fCurrentTids.put(ht.getHost(), cpu, ht);
}
/**
* Get the {@link OsWorker} object that is currently running on the CPU
* of a host
*
* @param host
* The identifier of the trace/machine of the CPU
* @param cpu
* The CPU ID on which the worker is running
* @return The {@link OsWorker} running on the CPU
*/
public @Nullable OsWorker getWorkerOnCpu(String host, Integer cpu) {
HostThread ht = fCurrentTids.get(host, cpu);
if (ht == null) {
return null;
}
return findWorker(ht);
}
/**
* Return the worker associated with this host TID
*
* @param ht
* The host thread associated with a worker
* @return The {@link OsWorker} associated with a host thread
*/
public @Nullable OsWorker findWorker(HostThread ht) {
return fWorkerMap.get(ht);
}
/**
* Add a new worker to the system
*
* @param worker
* The worker to add
*/
public void addWorker(OsWorker worker) {
fWorkerMap.put(worker.getHostThread(), worker);
}
/**
* Get the list of workers on this system
*
* @return The list of workers on the system
*/
public Collection<OsWorker> getWorkers() {
return fWorkerMap.values();
}
/**
* Pushes an interrupt context on the stack for a CPU on a host
*
* @param hostId
* The host ID of the trace/machine the interrupt context belongs
* to
* @param cpu
* The CPU this interrupt happened on
* @param interruptCtx
* The interrupt context to push on the stack
*/
public void pushContextStack(String hostId, Integer cpu, OsInterruptContext interruptCtx) {
Deque<OsInterruptContext> stack = fIntCtxStacks.get(hostId, cpu);
if (stack == null) {
stack = new ArrayDeque<>();
fIntCtxStacks.put(hostId, cpu, stack);
}
stack.addFirst(interruptCtx);
}
/**
* Peeks the top of the interrupt context stack for a CPU on a host, to see
* what is the latest context.
*
* @param hostId
* The host ID of the trace/machine the interrupt context belongs
* to
* @param cpu
* The CPU this interrupt happened on
* @return The latest interrupt context on the CPU of the host
*/
public OsInterruptContext peekContextStack(String hostId, Integer cpu) {
Deque<@NonNull OsInterruptContext> stack = fIntCtxStacks.get(hostId, cpu);
if (stack == null) {
return OsInterruptContext.DEFAULT_CONTEXT;
}
if (stack.isEmpty()) {
return OsInterruptContext.DEFAULT_CONTEXT;
}
return Objects.requireNonNull(stack.peekFirst());
}
/**
* Removes the top of the interrupt context stack for a CPU on a host and
* returns the result
*
* @param hostId
* The host ID of the trace/machine the interrupt context belongs
* to
* @param cpu
* The CPU this interrupt happened on
* @return The latest interrupt context on the CPU of the host
*/
public @Nullable OsInterruptContext popContextStack(String hostId, Integer cpu) {
Deque<OsInterruptContext> stack = fIntCtxStacks.get(hostId, cpu);
if (stack == null) {
return null;
}
if (stack.isEmpty()) {
return null;
}
return stack.removeFirst();
}
}