/******************************************************************************* * Copyright (c) 2006, 2008 g-Eclipse Consortium 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 Initial development of * the original code was made for the g-Eclipse project founded by European * Union project number: FP6-IST-034327 http://www.geclipse.eu/ Contributors: * Christof Klausecker GUP, JKU - initial API and implementation ******************************************************************************/ package eu.geclipse.traceview.debug.actions; import java.util.ArrayList; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import eu.geclipse.traceview.EventType; import eu.geclipse.traceview.IEvent; import eu.geclipse.traceview.ITrace; import eu.geclipse.traceview.ITraceView; import eu.geclipse.traceview.IVectorEvent; import eu.geclipse.traceview.debug.Activator; import eu.geclipse.traceview.debug.EventBreakpoint; import eu.geclipse.traceview.utils.VectorEventComparator; /** * Global Breakpoint Action */ public class GlobalBreakpointAction extends AbstractEventBreakpointAction { private int[] first; private int[] last; public void run( final IAction action ) { Object selectedObject = this.selection.getFirstElement(); if( selectedObject instanceof IEvent ) { IEvent event = ( IEvent )selectedObject; if( event.getType() == EventType.RECV ) { event = event.getPartnerEvent(); } ITrace trace = event.getProcess().getTrace(); // calculate breakpoint set boolean valid = createSet( event ); if( !valid ) { ErrorDialog.openError( Display.getDefault().getActiveShell(), "Cannot set global breakpoint", "Please select a different event.", new Status( IStatus.INFO, Activator.PLUGIN_ID, "There is no global breakpoint for this event." ) ); } else { // set breakpoints ArrayList<EventBreakpoint> eventBreakpoints = new ArrayList<EventBreakpoint>(); try { for( int i = 0; i < trace.getNumberOfProcesses(); i++ ) { if( this.last[ i ] != -1 && this.last[ i ] <= trace.getProcess( i ) .getMaximumLogicalClock() ) { EventBreakpoint eventBreakpoint = createEventBreakpoint( trace.getProcess( i ) .getEventByLogicalClock( this.last[ i ] ) ); eventBreakpoints.add( eventBreakpoint ); } } boolean add = true; for( EventBreakpoint e : eventBreakpoints ) { if( e == null ) { add = false; } } if( add ) { DebugPlugin.getDefault() .getBreakpointManager() .addBreakpoints( eventBreakpoints.toArray( new EventBreakpoint[ 0 ] ) ); } } catch( IndexOutOfBoundsException exception ) { Activator.logException( exception ); } catch( CoreException exception ) { Activator.logException( exception ); } // redraw traceview Display.getDefault().asyncExec( new Runnable() { public void run() { try { ITraceView traceView = ( ITraceView )PlatformUI.getWorkbench() .getActiveWorkbenchWindow() .getActivePage() .showView( "eu.geclipse.traceview.views.TraceView" ); //$NON-NLS-1$ traceView.redraw(); } catch( PartInitException partInitException ) { Activator.logException( partInitException ); } } } ); } } } private boolean createSet( final IEvent event ) { ITrace trace = event.getProcess().getTrace(); this.last = new int[ trace.getNumberOfProcesses() ]; this.first = new int[ trace.getNumberOfProcesses() ]; // get first and last IVectorEvent vectorEvent = ( IVectorEvent )event; VectorEventComparator comparator = new VectorEventComparator(); IVectorEvent vectorEvent2 = null; for( int i = 0; i < trace.getNumberOfProcesses(); i++ ) { if( i != event.getProcessId() ) { // first this.first[ i ] = vectorEvent.getLogicalClock(); if( trace.getProcess( i ).getMaximumLogicalClock() < this.first[ i ] ) { this.first[ i ] = trace.getProcess( i ).getMaximumLogicalClock(); } vectorEvent2 = ( IVectorEvent )trace.getProcess( i ) .getEventByLogicalClock( this.first[ i ] ); if( comparator.compare( vectorEvent2, vectorEvent ) < 0 ) { do { this.first[ i ]++; vectorEvent2 = ( IVectorEvent )trace.getProcess( i ) .getEventByLogicalClock( this.first[ i ] ); } while( vectorEvent2 != null && comparator.compare( vectorEvent2, vectorEvent ) < 0 ); } else if( comparator.compare( vectorEvent2, vectorEvent ) >= 0 ) { do { this.first[ i ]--; vectorEvent2 = ( IVectorEvent )trace.getProcess( i ) .getEventByLogicalClock( this.first[ i ] ); } while( this.first[ i ] > -1 && vectorEvent2 != null && comparator.compare( vectorEvent2, vectorEvent ) >= 0 ); this.first[ i ]++; } // last this.last[ i ] = vectorEvent.getLogicalClock(); if( trace.getProcess( i ).getMaximumLogicalClock() < this.last[ i ] ) { this.last[ i ] = trace.getProcess( i ).getMaximumLogicalClock(); } vectorEvent2 = ( IVectorEvent )trace.getProcess( i ) .getEventByLogicalClock( this.last[ i ] ); if( comparator.compare( vectorEvent2, vectorEvent ) <= 0 ) { do { this.last[ i ]++; vectorEvent2 = ( IVectorEvent )trace.getProcess( i ) .getEventByLogicalClock( this.last[ i ] ); } while( vectorEvent2 != null && comparator.compare( vectorEvent2, vectorEvent ) <= 0 ); } else if( comparator.compare( vectorEvent2, vectorEvent ) > 0 ) { do { this.last[ i ]--; vectorEvent2 = ( IVectorEvent )trace.getProcess( i ) .getEventByLogicalClock( this.last[ i ] ); } while( this.last[ i ] > -1 && vectorEvent2 != null && comparator.compare( vectorEvent2, vectorEvent ) > 0 ); this.last[ i ]++; } } else { this.first[ i ] = event.getLogicalClock(); this.last[ i ] = event.getLogicalClock(); } } // calc boolean changed = true; while( changed ) { changed = false; for( int i = 0; i < trace.getNumberOfProcesses(); i++ ) { int start = this.first[ i ]; while( start <= this.last[ i ] && !changed ) { IEvent e = trace.getProcess( i ).getEventByLogicalClock( start ); if( e != null && e.getPartnerLogicalClock() > this.last[ e.getPartnerProcessId() ] ) { if( start != this.last[ i ] ) { this.last[ i ] = start; changed = true; } } start++; } } } // for( int i = 0; i < trace.getNumberOfProcesses(); i++ ) { // System.out.println( i + " " + this.first[ i ] + " " + this.last[ i ] ); // } // check boolean valid = true; for( int i = 0; i < trace.getNumberOfProcesses(); i++ ) { if( this.first[ i ] != 0 ) { IEvent e = trace.getProcess( i ) .getEventByLogicalClock( this.first[ i ] - 1 ); if( e.getPartnerLogicalClock() > this.last[ e.getPartnerProcessId() ] ) { // System.out.println( i + " " + ( this.first[ i ] - 1 ) ); valid = false; break; } } for( int j = this.first[ i ]; j < this.last[ i ]; j++ ) { IEvent e = trace.getProcess( i ).getEventByLogicalClock( j ); if( e.getPartnerLogicalClock() > this.last[ e.getPartnerProcessId() ] ) { valid = false; break; } } } return valid; } }