1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-26 02:15:31 +02:00

Bug 405390 - [Visualizer] Implement selection-based filtering of the

multicore visualizer display

Change-Id: I516af7e4b625add754eaa1713ddc562a33f15c79
Reviewed-on: https://git.eclipse.org/r/12138
Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
IP-Clean: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
This commit is contained in:
Marc Dumais 2013-05-06 06:30:25 -04:00 committed by Marc-Andre Laperle
parent 933e401ef3
commit de790b478e
13 changed files with 734 additions and 43 deletions

View file

@ -1,5 +1,5 @@
# ============================================================================= # =============================================================================
# Copyright (c) 2012 Tilera Corporation and others. # Copyright (c) 2012, 2013 Tilera Corporation and others.
# All rights reserved. This program and the accompanying materials # All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0 # are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at # which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
# Contributors: # Contributors:
# William R. Swanson (Tilera Corporation) # William R. Swanson (Tilera Corporation)
# Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268) # Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268)
# Marc Dumais (Ericsson) - Bug 405390
# ============================================================================= # =============================================================================
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@ -32,3 +33,11 @@ MulticoreVisualizer.actions.SetLoadMeterPeriod.description=Choose the refresh sp
MulticoreVisualizer.actions.LoadMeterSubmenu.text=Load Meters MulticoreVisualizer.actions.LoadMeterSubmenu.text=Load Meters
MulticoreVisualizer.actions.LoadMetersRefreshSubSubmenu.text=Refresh Speed MulticoreVisualizer.actions.LoadMetersRefreshSubSubmenu.text=Refresh Speed
MulticoreVisualizer.actions.ClearFilter.text=Clear filter
MulticoreVisualizer.actions.SetFilter.text=Filter to selection
MulticoreVisualizer.view.CanvasFilter.Active.text=Filter Active:
MulticoreVisualizer.view.CanvasFilter.cpu.text=CPUs:
MulticoreVisualizer.view.CanvasFilter.core.text=Cores:
MulticoreVisualizer.view.CanvasFilter.thread.text=Threads:
MulticoreVisualizer.view.CanvasFilter.NotActive.text=Filter not active

View file

@ -0,0 +1,72 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson
* 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 405390)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view.MulticoreVisualizer;
import org.eclipse.cdt.visualizer.ui.VisualizerAction;
/**
* @since 1.1
*/
public class FilterCanvasAction extends VisualizerAction {
/** Visualizer instance we're associated with. */
MulticoreVisualizer m_visualizer = null;
boolean m_haveFilter = false;
/**
* @param filterType: the type of canvas object the filter applies-to. If null, reset filter
*/
public FilterCanvasAction(boolean enable) {
m_haveFilter = enable;
if (m_haveFilter) {
setText(MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.actions.SetFilter.text")); //$NON-NLS-1$
}
else {
setText(MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.actions.ClearFilter.text")); //$NON-NLS-1$
}
}
/** Dispose method. */
@Override
public void dispose()
{
m_visualizer = null;
super.dispose();
}
// --- init methods ---
/** Initializes this action for the specified view. */
public void init(MulticoreVisualizer visualizer)
{
m_visualizer = visualizer;
}
// --- methods ---
/** Invoked when action is triggered. */
@Override
public void run() {
if (m_visualizer != null) {
if (m_haveFilter) {
m_visualizer.applyCanvasFilter();
}
else {
m_visualizer.clearCanvasFilter();
}
}
}
}

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson
* 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 405390)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model;
/**
* Common interface for visualizer model objects
*/
public interface IVisualizerModelObject {
/** Get the ID of this model object */
public int getID();
/** Get the parent of this model object*/
public IVisualizerModelObject getParent();
/** Compare two IVisualizerModelObject */
public int compareTo(IVisualizerModelObject o);
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012 Tilera Corporation and others. * Copyright (c) 2012, 2013 Tilera Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors: * Contributors:
* William R. Swanson (Tilera Corporation) - initial API and implementation * William R. Swanson (Tilera Corporation) - initial API and implementation
* Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268) * Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268)
* Marc Dumais (Ericsson) - Bug 405390
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model;
@ -23,7 +24,7 @@ import java.util.List;
/** Represents single CPU. */ /** Represents single CPU. */
public class VisualizerCPU public class VisualizerCPU
implements Comparable<VisualizerCPU> implements Comparable<VisualizerCPU>, IVisualizerModelObject
{ {
// --- members --- // --- members ---
@ -78,10 +79,17 @@ public class VisualizerCPU
// --- accessors --- // --- accessors ---
/** Gets ID of this CPU. */ /** Gets ID of this CPU. */
@Override
public int getID() { public int getID() {
return m_id; return m_id;
} }
/** CPU has no parent - always returns null */
@Override
public IVisualizerModelObject getParent() {
return null;
}
/** sets the load info for this CPU /** sets the load info for this CPU
* @since 1.1*/ * @since 1.1*/
public synchronized void setLoadInfo (VisualizerLoadInfo info) { public synchronized void setLoadInfo (VisualizerLoadInfo info) {
@ -154,4 +162,14 @@ public class VisualizerCPU
return result; return result;
} }
/** IVisualizerModelObject version of compareTO() */
@Override
public int compareTo(IVisualizerModelObject o) {
if (o != null) {
if (o.getClass() == this.getClass()) {
return compareTo((VisualizerCPU)o);
}
}
return 1;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012 Tilera Corporation and others. * Copyright (c) 2012, 2013 Tilera Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,13 +8,15 @@
* Contributors: * Contributors:
* William R. Swanson (Tilera Corporation) - initial API and implementation * William R. Swanson (Tilera Corporation) - initial API and implementation
* Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268) * Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268)
* Marc Dumais (Ericsson) - Bug 405390
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model;
/** Represents single core of a CPU. */ /** Represents single core of a CPU. */
public class VisualizerCore public class VisualizerCore
implements Comparable<VisualizerCore> implements Comparable<VisualizerCore>, IVisualizerModelObject
{ {
// --- members --- // --- members ---
@ -60,10 +62,17 @@ public class VisualizerCore
} }
/** Gets Linux CPU ID of this core. */ /** Gets Linux CPU ID of this core. */
@Override
public int getID() { public int getID() {
return m_id; return m_id;
} }
/** Return CPU this core is on. */
@Override
public IVisualizerModelObject getParent() {
return getCPU();
}
/** sets the load info for this core /** sets the load info for this core
* @since 1.1*/ * @since 1.1*/
public synchronized void setLoadInfo (VisualizerLoadInfo info) { public synchronized void setLoadInfo (VisualizerLoadInfo info) {
@ -103,5 +112,16 @@ public class VisualizerCore
} }
return result; return result;
} }
/** IVisualizerModelObject version of compareTO() */
@Override
public int compareTo(IVisualizerModelObject o) {
if (o != null) {
if (o.getClass() == this.getClass()) {
return compareTo((VisualizerCore)o);
}
}
return 1;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012 Tilera Corporation and others. * Copyright (c) 2012, 2013 Tilera Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,7 +7,7 @@
* *
* Contributors: * Contributors:
* William R. Swanson (Tilera Corporation) - initial API and implementation * William R. Swanson (Tilera Corporation) - initial API and implementation
* Marc Dumais (Ericsson) - Initial API and implementation (Bug 396268) * Marc Dumais (Ericsson) - Bug 405390
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model;
@ -127,6 +127,21 @@ public class VisualizerModel
return m_cpus.size(); return m_cpus.size();
} }
/** Gets number of cores. */
public int getCoreCount() {
int count = 0;
for(VisualizerCPU cpu : m_cpus) {
count += cpu.getCoreCount();
}
return count;
}
/** Gets number of threads. */
public int getThreadCount () {
return m_threads.size();
}
/** Gets CPU with specified ID. */ /** Gets CPU with specified ID. */
public VisualizerCPU getCPU(int id) { public VisualizerCPU getCPU(int id) {
return m_cpuMap.get(id); return m_cpuMap.get(id);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012 Tilera Corporation and others. * Copyright (c) 2012, 2013 Tilera Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,13 +9,15 @@
* William R. Swanson (Tilera Corporation) - initial API and implementation * William R. Swanson (Tilera Corporation) - initial API and implementation
* Marc Khouzam (Ericsson) - Added knowledge about execution * Marc Khouzam (Ericsson) - Added knowledge about execution
* state and os/gdb thread ids * state and os/gdb thread ids
* Marc Dumais (Ericsson) - Bug 405390
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model; package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model;
/** Represents single thread. */ /** Represents single thread. */
public class VisualizerThread public class VisualizerThread
implements Comparable<VisualizerThread> implements Comparable<VisualizerThread>, IVisualizerModelObject
{ {
// --- members --- // --- members ---
@ -113,6 +115,18 @@ public class VisualizerThread
return m_tid; return m_tid;
} }
/** Gets thread id (tid). */
@Override
public int getID() {
return getTID();
}
/** Return core the thread is on */
@Override
public IVisualizerModelObject getParent() {
return getCore();
}
/** Gets gdb thread id. */ /** Gets gdb thread id. */
public int getGDBTID() { public int getGDBTID() {
return m_gdbtid; return m_gdbtid;
@ -155,4 +169,15 @@ public class VisualizerThread
} }
return result; return result;
} }
/** IVisualizerModelObject version of compareTo() */
@Override
public int compareTo(IVisualizerModelObject o) {
if (o != null) {
if (o.getClass() == this.getClass()) {
return compareTo((VisualizerThread)o);
}
}
return 1;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012 Ericsson and others. * Copyright (c) 2012, 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -76,6 +76,9 @@ public class IMulticoreVisualizerConstants
*/ */
public static final Color COLOR_LOAD_TEXT = Colors.GREEN; public static final Color COLOR_LOAD_TEXT = Colors.GREEN;
/** Color used to draw text to the status bar */
public static final Color COLOR_STATUS_BAR_TEXT = Colors.GREEN;
// Colors for load meters // Colors for load meters
/** /**

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012 Tilera Corporation and others. * Copyright (c) 2012, 2013 Tilera Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,7 @@
* Marc Dumais (Ericsson) - Bug 399281 * Marc Dumais (Ericsson) - Bug 399281
* Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268) * Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268)
* Marc Dumais (Ericsson) - Bug 399419 * Marc Dumais (Ericsson) - Bug 399419
* Marc Dumais (Ericsson) - Bug 405390
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view;
@ -29,6 +30,7 @@ import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.EnableLoadMetersAction; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.EnableLoadMetersAction;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.FilterCanvasAction;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.RefreshAction; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.RefreshAction;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.SelectAllAction; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.SelectAllAction;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.SetLoadMeterPeriodAction; import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions.SetLoadMeterPeriodAction;
@ -197,6 +199,11 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer
/** Menu action */ /** Menu action */
List<SetLoadMeterPeriodAction> m_setLoadMeterPeriodActions = null; List<SetLoadMeterPeriodAction> m_setLoadMeterPeriodActions = null;
/** Menu action */
FilterCanvasAction m_setFilterAction = null;
/** Menu action */
FilterCanvasAction m_clearFilterAction = null;
// --- constructors/destructors --- // --- constructors/destructors ---
@ -339,6 +346,23 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer
return (MulticoreVisualizerCanvas) getCanvas(); return (MulticoreVisualizerCanvas) getCanvas();
} }
/** Sets-up a canvas filter */
public void applyCanvasFilter() {
m_canvas.applyFilter();
refresh();
}
/** Removes current canvas filter */
public void clearCanvasFilter() {
m_canvas.clearFilter();
refresh();
}
/** Tells if a canvas filter is in effect */
public boolean isCanvasFilterActive() {
return m_canvas.isFilterActive();
}
/** Return the data model backing this multicore visualizer */ /** Return the data model backing this multicore visualizer */
public VisualizerModel getModel() { public VisualizerModel getModel() {
return fDataModel; return fDataModel;
@ -415,6 +439,16 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer
defaultAction.setChecked(true); defaultAction.setChecked(true);
defaultAction.run(); defaultAction.run();
// canvas filter actions - they will be dynamically enabled/disabled
// according to canvas selection
m_setFilterAction = new FilterCanvasAction(true);
m_setFilterAction.init(this);
m_setFilterAction.setEnabled(false);
m_clearFilterAction = new FilterCanvasAction(false);
m_clearFilterAction.init(this);
m_clearFilterAction.setEnabled(false);
// Note: debug view may not be initialized at startup, // Note: debug view may not be initialized at startup,
// so we'll pretend the actions are not yet updated, // so we'll pretend the actions are not yet updated,
// and reinitialize them later. // and reinitialize them later.
@ -429,6 +463,13 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer
boolean enabled = hasSelection(); boolean enabled = hasSelection();
m_selectAllAction.setEnabled(enabled); m_selectAllAction.setEnabled(enabled);
m_refreshAction.setEnabled(enabled); m_refreshAction.setEnabled(enabled);
// enable "filter-to selection" menu item if there is a
// canvas selection
m_setFilterAction.setEnabled(m_canvas.hasSelection());
// enable "Clear filter" menu item if filter is active
m_clearFilterAction.setEnabled(isCanvasFilterActive());
// show the load meter refresh speed sub-menu only // show the load meter refresh speed sub-menu only
// if the load meters are enabled // if the load meters are enabled
@ -515,6 +556,16 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer
m_setLoadMeterPeriodActions = null; m_setLoadMeterPeriodActions = null;
} }
if (m_setFilterAction != null) {
m_setFilterAction.dispose();
m_setFilterAction = null;
}
if (m_clearFilterAction != null) {
m_clearFilterAction.dispose();
m_clearFilterAction = null;
}
m_actionsInitialized = false; m_actionsInitialized = false;
} }
@ -592,6 +643,11 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer
m_loadMetersRefreshSubSubmenu.add(act); m_loadMetersRefreshSubSubmenu.add(act);
} }
// add filtering options
menuManager.add(m_separatorAction);
menuManager.add(m_setFilterAction);
menuManager.add(m_clearFilterAction);
updateActions(); updateActions();
Point location = m_viewer.getContextMenuLocation(); Point location = m_viewer.getContextMenuLocation();
updateContextMenuActions(location); updateContextMenuActions(location);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012 Tilera Corporation and others. * Copyright (c) 2012, 2013 Tilera Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -15,6 +15,7 @@
* Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268) * Marc Dumais (Ericsson) - Add CPU/core load information to the multicore visualizer (Bug 396268)
* Marc Dumais (Ericsson) - Bug 399419 * Marc Dumais (Ericsson) - Bug 399419
* Marc Dumais (Ericsson) - Bug 404894 * Marc Dumais (Ericsson) - Bug 404894
* Marc Dumais (Ericsson) - Bug 405390
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view;
@ -139,6 +140,11 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
/** Selected PIDs. */ /** Selected PIDs. */
protected HashSet<Integer> m_selectedPIDs = null; protected HashSet<Integer> m_selectedPIDs = null;
/** Display filter for the graphical objects */
protected MulticoreVisualizerCanvasFilter m_canvasFilter = null;
/** Canvas status bar */
protected MulticoreVisualizerStatusBar m_statusBar = null;
// --- constructors/destructors --- // --- constructors/destructors ---
@ -228,6 +234,12 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
}; };
m_updateTimer.setRepeating(false); // one-shot timer m_updateTimer.setRepeating(false); // one-shot timer
m_updateTimer.start(); m_updateTimer.start();
// canvas filter
m_canvasFilter = new MulticoreVisualizerCanvasFilter(this);
// status bar
m_statusBar = new MulticoreVisualizerStatusBar();
} }
/** Cleans up control */ /** Cleans up control */
@ -276,6 +288,14 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
m_selectedPIDs.clear(); m_selectedPIDs.clear();
m_selectedPIDs = null; m_selectedPIDs = null;
} }
if (m_canvasFilter != null) {
m_canvasFilter.dispose();
m_canvasFilter = null;
}
if (m_statusBar != null) {
m_statusBar.dispose();
m_statusBar = null;
}
} }
@ -291,6 +311,8 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
public void setModel(VisualizerModel model) public void setModel(VisualizerModel model)
{ {
m_model = model; m_model = model;
// TODO : Consider clearing the filter if the model changes,
// by calling clearFilter()
requestRecache(); requestRecache();
requestUpdate(); requestUpdate();
} }
@ -355,6 +377,10 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
m_recacheState |= state; m_recacheState |= state;
m_recacheSizes |= sizes; m_recacheSizes |= sizes;
m_recacheLoadMeters |= load; m_recacheLoadMeters |= load;
// clear status bar message
m_statusBar.setMessage(null);
// re-compute filter to reflect latest model changes
m_canvasFilter.updateFilter();
} }
/** Fits n square items into a rectangle of the specified size. /** Fits n square items into a rectangle of the specified size.
@ -411,13 +437,19 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
for (VisualizerCPU cpu : m_model.getCPUs()) { for (VisualizerCPU cpu : m_model.getCPUs()) {
//if (force_cpu_count >= cpu_count) break; //if (force_cpu_count >= cpu_count) break;
//cpu_count++; //cpu_count++;
MulticoreVisualizerCPU mcpu = new MulticoreVisualizerCPU(cpu.getID()); // filter permits displaying this CPU?
m_cpus.add(mcpu); if (m_canvasFilter.displayObject(cpu)) {
m_cpuMap.put(cpu, mcpu); MulticoreVisualizerCPU mcpu = new MulticoreVisualizerCPU(cpu.getID());
for (VisualizerCore core : cpu.getCores()) { m_cpus.add(mcpu);
MulticoreVisualizerCore mcore = new MulticoreVisualizerCore(mcpu, core.getID()); m_cpuMap.put(cpu, mcpu);
m_cores.add(mcore); for (VisualizerCore core : cpu.getCores()) {
m_coreMap.put(core, mcore); // filter permits displaying this core?
if (m_canvasFilter.displayObject(core)) {
MulticoreVisualizerCore mcore = new MulticoreVisualizerCore(mcpu, core.getID());
m_cores.add(mcore);
m_coreMap.put(core, mcore);
}
}
} }
} }
} }
@ -442,19 +474,25 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
while (modelCpus.hasMoreElements()) { while (modelCpus.hasMoreElements()) {
VisualizerCPU modelCpu = modelCpus.nextElement(); VisualizerCPU modelCpu = modelCpus.nextElement();
MulticoreVisualizerCPU visualizerCpu = m_cpuMap.get(modelCpu); MulticoreVisualizerCPU visualizerCpu = m_cpuMap.get(modelCpu);
// update CPUs load meter // when filtering is active, not all objects might be in the map
MulticoreVisualizerLoadMeter meter = visualizerCpu.getLoadMeter(); if (visualizerCpu != null) {
meter.setEnabled(m_model.getLoadMetersEnabled()); // update CPUs load meter
meter.setLoad(modelCpu.getLoad()); MulticoreVisualizerLoadMeter meter = visualizerCpu.getLoadMeter();
meter.setHighLoadWatermark(modelCpu.getHighLoadWatermark());
for (VisualizerCore modelCore : modelCpu.getCores()) {
MulticoreVisualizerCore visualizerCore = m_coreMap.get(modelCore);
// update cores load meter
meter = visualizerCore.getLoadMeter();
meter.setEnabled(m_model.getLoadMetersEnabled()); meter.setEnabled(m_model.getLoadMetersEnabled());
meter.setLoad(modelCore.getLoad()); meter.setLoad(modelCpu.getLoad());
meter.setHighLoadWatermark(modelCore.getHighLoadWatermark()); meter.setHighLoadWatermark(modelCpu.getHighLoadWatermark());
for (VisualizerCore modelCore : modelCpu.getCores()) {
MulticoreVisualizerCore visualizerCore = m_coreMap.get(modelCore);
// when filtering is active, not all objects might be in the map
if (visualizerCore != null) {
// update cores load meter
meter = visualizerCore.getLoadMeter();
meter.setEnabled(m_model.getLoadMetersEnabled());
meter.setLoad(modelCore.getLoad());
meter.setHighLoadWatermark(modelCore.getHighLoadWatermark());
}
}
} }
} }
} }
@ -474,6 +512,14 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
// General margin/spacing constants. // General margin/spacing constants.
int cpu_margin = 8; // margin around edges of CPU grid int cpu_margin = 8; // margin around edges of CPU grid
int cpu_separation = 6; // spacing between CPUS int cpu_separation = 6; // spacing between CPUS
int statusBarHeight;
// reserve space for status bar only if filter is active
if (isFilterActive()) {
statusBarHeight = 20;
}
else {
statusBarHeight = 0;
}
// make room when load meters are present, else use a more compact layout // make room when load meters are present, else use a more compact layout
int core_margin = m_model.getLoadMetersEnabled() ? 20 : 12; // margin around cores in a CPU int core_margin = m_model.getLoadMetersEnabled() ? 20 : 12; // margin around cores in a CPU
@ -490,13 +536,27 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
// Figure out area to allocate to each CPU box. // Figure out area to allocate to each CPU box.
int ncpus = m_cpus.size(); int ncpus = m_cpus.size();
int width = bounds.width + cpu_separation; int width = bounds.width + cpu_separation;
int height = bounds.height + cpu_separation; int height = bounds.height + cpu_separation - statusBarHeight;
// put status bar at the bottom of the canvas area
m_statusBar.setBounds(cpu_margin, bounds.y + bounds.height - 2 * cpu_margin , width , statusBarHeight);
int cpu_edge = fitSquareItems(ncpus, width, height); int cpu_edge = fitSquareItems(ncpus, width, height);
int cpu_size = cpu_edge - cpu_separation; int cpu_size = cpu_edge - cpu_separation;
if (cpu_size < 0) cpu_size = 0; if (cpu_size < 0) cpu_size = 0;
// Calculate area on each CPU for placing cores. // Calculate area on each CPU for placing cores.
int ncores = m_cores.size() / ((ncpus == 0) ? 1 : ncpus); int ncores = 0;
// find the greatest number of cores on a given CPU and use
// that number for size calculations for all CPUs - this way
// we avoid displaying cores of varying sizes, in different
// CPUs.
for (MulticoreVisualizerCPU cpu : m_cpus) {
int n = cpu.getCores().size();
if (n > ncores) {
ncores = n;
}
}
int cpu_width = cpu_size - core_margin * 2 + core_separation; int cpu_width = cpu_size - core_margin * 2 + core_separation;
int cpu_height = cpu_size - core_margin * 2 + core_separation; int cpu_height = cpu_size - core_margin * 2 + core_separation;
int core_edge = fitSquareItems(ncores, cpu_width, cpu_height); int core_edge = fitSquareItems(ncores, cpu_width, cpu_height);
@ -572,14 +632,17 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
// like processes and threads // like processes and threads
for (VisualizerThread thread : m_model.getThreads()) { for (VisualizerThread thread : m_model.getThreads()) {
VisualizerCore core = thread.getCore(); // filter permits displaying this thread?
MulticoreVisualizerCore mcore = m_coreMap.get(core); if(m_canvasFilter.displayObject(thread)) {
if (mcore != null) { VisualizerCore core = thread.getCore();
MulticoreVisualizerThread mthread = MulticoreVisualizerCore mcore = m_coreMap.get(core);
new MulticoreVisualizerThread(mcore, thread); if (mcore != null) {
mcore.addThread(mthread); MulticoreVisualizerThread mthread =
m_threads.add(mthread); new MulticoreVisualizerThread(mcore, thread);
m_threadMap.put(thread, mthread); mcore.addThread(mthread);
m_threads.add(mthread);
m_threadMap.put(thread, mthread);
}
} }
} }
@ -658,6 +721,12 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
thread.paintContent(gc); thread.paintContent(gc);
} }
// paint status bar
if (m_canvasFilter.isFilterActive()) {
m_statusBar.setMessage(m_canvasFilter.toString());
m_statusBar.paintContent(gc);
}
// paint drag-selection marquee last, so it's on top. // paint drag-selection marquee last, so it's on top.
m_marquee.paintContent(gc); m_marquee.paintContent(gc);
} }
@ -1025,4 +1094,22 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas
public void setSelectionEventsEnabled(boolean enabled) { public void setSelectionEventsEnabled(boolean enabled) {
m_selectionManager.setSelectionEventsEnabled(enabled); m_selectionManager.setSelectionEventsEnabled(enabled);
} }
// --- canvas filter methods ---
/** Set-up a canvas white-list filter. */
public void applyFilter() {
m_canvasFilter.applyFilter();
}
/** Removes any canvas filter currently in place */
public void clearFilter() {
m_canvasFilter.clearFilter();
}
/** Tells if a canvas filter is currently in place */
public boolean isFilterActive() {
return m_canvasFilter.isFilterActive();
}
} }

View file

@ -0,0 +1,300 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson
* 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 405390)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.MulticoreVisualizerUIPlugin;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.IVisualizerModelObject;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCPU;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerCore;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerModel;
import org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model.VisualizerThread;
import org.eclipse.cdt.visualizer.ui.util.SelectionUtils;
import org.eclipse.jface.viewers.ISelection;
/**
* White-list Filter for the graphical objects displayed in the multicore
* visualizer canvas.
*/
public class MulticoreVisualizerCanvasFilter {
/** The white list */
List<IVisualizerModelObject> m_filterList = null;
/** the dynamically expanded list, containing elements in the */
/** white list and their parents - recalculated as required */
/** since some elements can move around and change parent */
List<IVisualizerModelObject> m_dynamicFilterList = null;
/** reference to the canvas */
private MulticoreVisualizerCanvas m_canvas = null;
/** is the filter is active/set */
private boolean m_filterActive = false;
/** for stats */
private int m_shownCpu = 0;
/** for stats */
private int m_shownCore = 0;
/** for stats */
private int m_shownThread = 0;
/** for stats */
private int m_totalCpu = 0;
/** for stats */
private int m_totalCore = 0;
/** for stats */
private int m_totalThread = 0;
/** String constant used in this class */
private static final String STR_FILTER_NOT_ACTIVE = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.NotActive.text"); //$NON-NLS-1$
/** String constant used in this class */
private static final String STR_FILTER_ACTIVE = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.Active.text"); //$NON-NLS-1$
/** String constant used in this class */
private static final String STR_CPU = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.cpu.text"); //$NON-NLS-1$
/** String constant used in this class */
private static final String STR_CORE = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.core.text"); //$NON-NLS-1$
/** String constant used in this class */
private static final String STR_THREAD = MulticoreVisualizerUIPlugin.getString("MulticoreVisualizer.view.CanvasFilter.thread.text"); //$NON-NLS-1$
// --- constructors/destructors ---
/** Constructor. */
public MulticoreVisualizerCanvasFilter(MulticoreVisualizerCanvas canvas) {
m_canvas = canvas;
}
/** Dispose method */
public void dispose() {
clearFilter();
m_canvas = null;
}
// --- filter methods ---
/**
* Set-up a canvas white-list filter. Any applicable selected object is added to
* the filter.
*/
public void applyFilter() {
// replace current filter? Clear old one first.
if (isFilterActive()) {
clearFilter();
}
m_filterList = new ArrayList<IVisualizerModelObject>();
m_dynamicFilterList = new ArrayList<IVisualizerModelObject>();
m_filterActive = true;
// get list of selected objects the filter applies-for
ISelection selection = m_canvas.getSelection();
List<Object> selectedObjects = SelectionUtils.getSelectedObjects(selection);
for (Object obj : selectedObjects) {
if (obj instanceof IVisualizerModelObject) {
m_filterList.add((IVisualizerModelObject)obj);
}
}
}
/** Removes any canvas filter currently in place */
public void clearFilter() {
if (m_filterList != null) {
m_filterList.clear();
m_filterList = null;
}
if (m_dynamicFilterList != null) {
m_dynamicFilterList.clear();
m_dynamicFilterList = null;
}
resetCounters();
m_filterActive = false;
}
/** tells if a canvas filter is currently in place */
public boolean isFilterActive() {
return m_filterActive;
}
/**
* Updates the filter to contain the up-to-date parent objects,
* for all filter objects.
*/
public void updateFilter() {
if (m_filterList == null)
return;
resetCounters();
m_dynamicFilterList.clear();
for (IVisualizerModelObject elem : m_filterList) {
// element still in current model?
if (isElementInCurrentModel(elem)) {
// add element to list
addElementToFilterList(elem);
// also add all its ancestors
IVisualizerModelObject parent = elem.getParent();
while (parent != null) {
addElementToFilterList(parent);
parent = parent.getParent();
}
}
}
}
/**
* Tells if a candidate model object should be displayed, according to the
* filter in place.
*/
public boolean displayObject(final IVisualizerModelObject candidate) {
// filter not active? Let anything be displayed
if (!m_filterActive) {
return true;
}
// Candidate is in white list?
if (isElementInFilterList(candidate)) {
return true;
}
return false;
}
// --- filter list management ---
/**
* Adds an element to the dynamic filter list, if an equivalent
* element is not already there.
*/
private void addElementToFilterList(final IVisualizerModelObject elem) {
if (!isElementInFilterList(elem)) {
m_dynamicFilterList.add(elem);
stepStatsCounter(elem);
}
}
/**
* Checks if an element already has an equivalent in the
* dynamic filter list.
*/
private boolean isElementInFilterList(final IVisualizerModelObject candidate) {
// is the candidate in the dynamic filter list?
for (IVisualizerModelObject elem : m_dynamicFilterList) {
// Note: we are comparing the content (IDs), not references.
if (candidate.compareTo(elem) == 0) {
return true;
}
}
return false;
}
/** Used to check if model elements in the filter still exist in the current model. */
private boolean isElementInCurrentModel(IVisualizerModelObject element) {
VisualizerModel model = m_canvas.getModel();
if (model != null) {
if (element instanceof VisualizerThread) {
VisualizerThread thread = model.getThread(((VisualizerThread) element).getGDBTID());
if (thread != null) {
// Note: we are comparing the content (IDs), not references.
if (thread.compareTo(element) == 0) {
return true;
}
}
}
else if (element instanceof VisualizerCore) {
VisualizerCore core = model.getCore(element.getID());
if (core != null) {
// Note: we are comparing the content (IDs), not references.
if (core.compareTo(element) == 0) {
return true;
}
}
}
else if (element instanceof VisualizerCPU) {
VisualizerCPU cpu = model.getCPU(element.getID());
if (cpu != null) {
// Note: we are comparing the content (IDs), not references.
if (cpu.compareTo(element) == 0) {
return true;
}
}
}
}
return false;
}
// --- Stats counters ---
/**
* Used to step the filtered counters for a given type of
* model object.
*/
private void stepStatsCounter(IVisualizerModelObject modelObj) {
if (modelObj instanceof VisualizerCPU) {
m_shownCpu++;
}
else if (modelObj instanceof VisualizerCore) {
m_shownCore++;
}
else if (modelObj instanceof VisualizerThread) {
m_shownThread++;
}
}
/** Reset the filtering counters */
private void resetCounters() {
m_shownCpu = 0;
m_shownCore = 0;
m_shownThread = 0;
// refresh total counts since the model can change
if (m_canvas != null) {
VisualizerModel model = m_canvas.getModel();
if (model != null) {
m_totalCpu = model.getCPUCount();
m_totalCore = model.getCoreCount();
m_totalThread = model.getThreadCount();
}
}
}
/** returns a String giving the current filtering stats */
private String getStats() {
return STR_FILTER_ACTIVE + " " + STR_CPU + " " + m_shownCpu + "/" + m_totalCpu + ", " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
STR_CORE + " " + m_shownCore + "/" + m_totalCore + ", " + //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
STR_THREAD + " " + m_shownThread + "/" + m_totalThread; //$NON-NLS-1$//$NON-NLS-2$
}
@Override
public String toString() {
if (isFilterActive()) {
return getStats();
}
else {
return STR_FILTER_NOT_ACTIVE;
}
}
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012 Ericsson and others. * Copyright (c) 2012, 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,6 +9,7 @@
* Marc Khouzam (Ericsson) - initial API and implementation * Marc Khouzam (Ericsson) - initial API and implementation
* Marc Dumais (Ericsson) - Bug 400231 * Marc Dumais (Ericsson) - Bug 400231
* Marc Dumais (Ericsson) - Bug 399419 * Marc Dumais (Ericsson) - Bug 399419
* Marc Dumais (Ericsson) - Bug 405390
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view;
@ -122,7 +123,7 @@ public class MulticoreVisualizerEventListener {
thread.setState(newState); thread.setState(newState);
thread.setCore(vCore); thread.setCore(vCore);
fVisualizer.getMulticoreVisualizerCanvas().requestUpdate(); fVisualizer.refresh();
} }
} }
} }

View file

@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson
* 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 405390)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view;
import org.eclipse.cdt.visualizer.ui.util.GUIUtils;
import org.eclipse.swt.graphics.GC;
public class MulticoreVisualizerStatusBar extends MulticoreVisualizerGraphicObject {
// --- members ---
/** message to display in status bar */
protected String m_statusMessage = null;
// --- constructors/destructors ---
/** Constructor */
public MulticoreVisualizerStatusBar() {
}
/** Dispose method */
@Override
public void dispose() {
super.dispose();
m_statusMessage = null;
}
// --- accessors ---
public void setMessage (String message) {
m_statusMessage = message;
}
// --- paint methods ---
/** Invoked to allow element to paint itself on the viewer canvas */
@Override
public void paintContent(GC gc) {
if (m_statusMessage == null)
return;
// Display message text
gc.setForeground(IMulticoreVisualizerConstants.COLOR_STATUS_BAR_TEXT);
int tx = m_bounds.x;
int ty = m_bounds.y + 15;
GUIUtils.drawTextAligned(gc, m_statusMessage, tx, ty, true, false);
}
}