diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java index 0b2f5dfdbca..248d1213288 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java @@ -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 coreInfo = new Vector(); @@ -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 coreInfo = new Vector(); + + 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()]); } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardwareAndOS.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardwareAndOS.java index 49740b4e78a..0d7a412e25e 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardwareAndOS.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardwareAndOS.java @@ -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 cpuIds = new HashSet(); 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 coreDmcs = new Vector(); for (ICoreInfo core : coresInfo) { diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardwareAndOS_7_10.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardwareAndOS_7_10.java new file mode 100644 index 00000000000..1275cf57bfb --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardwareAndOS_7_10.java @@ -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 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(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 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(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); + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java index cdd6ee67e59..a676656e700 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java @@ -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); }