1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 464184 - Update GDBHardwareAndOS service to take advantage of GDB

providing CPU/core info

Change-Id: I9d6ce989d9b71e7dd83f3d395da972d43486345c
This commit is contained in:
Marc Dumais 2015-04-08 12:42:56 -04:00 committed by Gerrit Code Review @ Eclipse.org
parent 3bd061e4ee
commit 9ea9dd867c
4 changed files with 205 additions and 12 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson and others.
* Copyright (c) 2012, 2015 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial API and implementation
* Marc Dumais (Ericsson) - bug 464184
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal;
@ -18,6 +19,7 @@ import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Vector;
import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS2.IResourcesInformation;
import org.eclipse.cdt.internal.core.ICoreInfo;
/**
@ -26,26 +28,54 @@ public class CoreList {
private ICoreInfo[] fCoreList;
private String fCoreFileName;
private IResourcesInformation fResourcesInfo;
private static final String PROCESSOR_ID_STR = "processor"; //$NON-NLS-1$
private static final String PHYSICAL_ID_STR = "physical id"; //$NON-NLS-1$
/** Default constructor - assumes the info comes from file /proc/cpuinfo */
public CoreList() {
fCoreFileName = "/proc/cpuinfo"; //$NON-NLS-1$
}
/** Alternate constructor - info comes from a file passed as parameter */
public CoreList(String fileName) {
fCoreFileName = fileName;
}
/**
* Alternate constructor - info comes from IResourcesInformation object,
* that was obtained from GDB
*/
public CoreList(IResourcesInformation info) {
fResourcesInfo = info;
}
/** Returns the list of cores. The core information will only
* be parsed once and the result cached. To force a re-parse,
* one must create a new CoreList object. */
public ICoreInfo[] getCoreList() {
// already parsed info?
if (fCoreList != null) {
return fCoreList;
}
if (fCoreFileName != null) {
getCoreListFromFile();
}
else if (fResourcesInfo != null) {
getCoreListFromResourceInfo();
}
return fCoreList;
}
/**
* Returns the list of cores as shown in /proc/cpuinfo
* This method will only parse /proc/cpuinfo once and cache
* the result. To force a re-parse, one must create a new
* CoreList object.
*/
public ICoreInfo[] getCoreList() {
if (fCoreList != null) {
return fCoreList;
}
private void getCoreListFromFile() {
File cpuInfo = new File(fCoreFileName);
Vector<ICoreInfo> coreInfo = new Vector<ICoreInfo>();
@ -59,7 +89,7 @@ public class CoreList {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith("processor")) { //$NON-NLS-1$
if (line.startsWith(PROCESSOR_ID_STR)) {
if (processorId != null) {
// We are already at the next 'processor' entry, without
// having found the 'physical id' entry. This means
@ -71,7 +101,7 @@ public class CoreList {
}
// Found the processor id of this core, so store it temporarily
processorId = line.split(":")[1].trim(); //$NON-NLS-1$
} else if (line.startsWith("physical id")) { //$NON-NLS-1$
} else if (line.startsWith(PHYSICAL_ID_STR)) {
// Found the physical id of this core, so store it temporarily
assert physicalId == null;
@ -99,6 +129,50 @@ public class CoreList {
}
fCoreList = coreInfo.toArray(new ICoreInfo[coreInfo.size()]);
return fCoreList;
}
private void getCoreListFromResourceInfo() {
Vector<ICoreInfo> coreInfo = new Vector<ICoreInfo>();
int processorIdIndex = -1;
int physicalIdIndex = -1;
String processorId = null;
String physicalId = null;
int column = 0;
// find the indexes of the columns that we need
for (String col : fResourcesInfo.getColumnNames()) {
if (col.equalsIgnoreCase(PROCESSOR_ID_STR)) {
processorIdIndex = column;
}
else if (col.equalsIgnoreCase(PHYSICAL_ID_STR)) {
physicalIdIndex = column;
}
column++;
}
if (processorIdIndex >= 0) {
// for each entry
for (String[] line : fResourcesInfo.getContent()) {
processorId = line[processorIdIndex];
if (physicalIdIndex >= 0) {
physicalId = line[physicalIdIndex];
}
// This will happen when there is no 'physical id' field. This means
// there is a single physical CPU.
else {
physicalId = "0"; //$NON-NLS-1$
}
coreInfo.add(new CoreInfo(processorId, physicalId));
// Get ready to look for the next core.
processorId = null;
physicalId = null;
}
}
fCoreList = coreInfo.toArray(new ICoreInfo[coreInfo.size()]);
}
}

View file

@ -11,6 +11,7 @@
* Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268)
* Marc Dumais (Ericsson) - Bug 434889
* Teodor Madan (Freescale) - Activate multicore visualizer on non-linux hosts for remote case
* Marc Dumais (Ericsson) - Bug 464184
*
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -387,7 +388,7 @@ public class GDBHardwareAndOS extends AbstractDsfService implements IGDBHardware
/**
* Parse the CoreInfo and create the CPU Contexts for the hardwareTarget context.
*/
private ICPUDMContext[] parseCoresInfoForCPUs(IHardwareTargetDMContext dmc, ICoreInfo[] coresInfo) {
ICPUDMContext[] parseCoresInfoForCPUs(IHardwareTargetDMContext dmc, ICoreInfo[] coresInfo) {
Set<String> cpuIds = new HashSet<String>();
ICPUDMContext[] CPUs;
@ -406,7 +407,7 @@ public class GDBHardwareAndOS extends AbstractDsfService implements IGDBHardware
/**
* Parse the CoreInfo and create the Core Contexts for the specified CPU context.
*/
private ICoreDMContext[] parseCoresInfoForCores(ICPUDMContext cpuDmc, ICoreInfo[] coresInfo) {
ICoreDMContext[] parseCoresInfoForCores(ICPUDMContext cpuDmc, ICoreInfo[] coresInfo) {
Vector<ICoreDMContext> coreDmcs = new Vector<ICoreDMContext>();
for (ICoreInfo core : coresInfo) {

View file

@ -0,0 +1,111 @@
/*******************************************************************************
* Copyright (c) 2015 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Dumais (Ericsson) - Initial API and implementation (bug 464184)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.gdb.internal.CoreList;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.internal.core.ICoreInfo;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
* This extension to the GDBHardwareAndOS service takes advantage of GDB providing CPU information (on Linux)
* @since 4.7
*/
public class GDBHardwareAndOS_7_10 extends GDBHardwareAndOS_7_5 {
private ICoreInfo[] coreListCache;
final static String CPUResourceClass = "cpus"; //$NON-NLS-1$
/** constructor */
public GDBHardwareAndOS_7_10(DsfSession session) {
super(session);
}
@Override
public void getCPUs(final IHardwareTargetDMContext dmc, final DataRequestMonitor<ICPUDMContext[]> rm) {
if (!getSessionInitializationComplete()) {
// We are not ready to answer yet
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Debug session not initialized yet", null)); //$NON-NLS-1$
return;
}
if (coreListCache != null) {
rm.done(parseCoresInfoForCPUs(dmc, coreListCache));
return;
}
getResourcesInformation(dmc, CPUResourceClass, new DataRequestMonitor<IResourcesInformation>(getExecutor(), rm) {
@Override
@ConfinedToDsfExecutor("getExecutor()")
protected void handleCompleted() {
if (isSuccess()) {
coreListCache = new CoreList(getData()).getCoreList();
rm.done(parseCoresInfoForCPUs(dmc, coreListCache));
}
else {
// not Linux?
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$
}
}
});
}
@Override
public void getCores(IDMContext dmc, final DataRequestMonitor<ICoreDMContext[]> rm) {
if (!getSessionInitializationComplete()) {
// We are not ready to answer yet
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Debug session not initialized yet", null)); //$NON-NLS-1$
return;
}
if (dmc instanceof ICPUDMContext) {
// Get the cores under this particular CPU
final ICPUDMContext cpuDmc = (ICPUDMContext)dmc;
if (coreListCache != null) {
rm.done(parseCoresInfoForCores(cpuDmc, coreListCache));
return;
}
getResourcesInformation(dmc, CPUResourceClass, new DataRequestMonitor<IResourcesInformation>(getExecutor(), rm) {
@Override
@ConfinedToDsfExecutor("getExecutor()")
protected void handleCompleted() {
if (isSuccess()) {
coreListCache = new CoreList(getData()).getCoreList();
rm.done(parseCoresInfoForCores(cpuDmc, coreListCache));
}
else {
// not Linux?
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$
}
}
});
}
else {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
}
}
@Override
public void flushCache(IDMContext context) {
coreListCache = null;
super.flushCache(context);
}
}

View file

@ -18,6 +18,7 @@
* Marc Khouzam (Ericsson) - Support for GDB 7.4 processes service (Bug 389945)
* Marc Khouzam (Ericsson) - Support dynamic printf in bp service 7.5 (Bug 400628)
* Alvaro Sanchez-Leon (Ericsson) - Allow user to edit the register groups (Bug 235747)
* Marc Dumais (Ericsson) - Update GDBHardwareAndOS service to take advantage of GDB providing CPU/core info (bug 464184)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -76,6 +77,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
public static final String GDB_7_6_VERSION = "7.5.50"; //$NON-NLS-1$
/** @since 4.4 */
public static final String GDB_7_7_VERSION = "7.7"; //$NON-NLS-1$
/** @since 4.7 */
// TODO: replace with version 7.10, when released
private static final String GDB_7_10_VERSION = "7.9.50.20150402"; //$NON-NLS-1$
private final String fVersion;
@ -280,6 +284,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
/** @since 4.1 */
protected IGDBHardwareAndOS createHardwareAndOSService(DsfSession session, ILaunchConfiguration config) {
if (GDB_7_10_VERSION.compareTo(fVersion) <= 0) {
return new GDBHardwareAndOS_7_10(session);
}
if (GDB_7_5_VERSION.compareTo(fVersion) <= 0) {
return new GDBHardwareAndOS_7_5(session);
}