blob: 0076f5a2f896041fcd0c92dcdc602e7c98ad1fe1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 The Regents of the University of California.
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly marked,
* so as not to confuse it with the version available from LANL.
*
* Additionally, 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
*
* LA-CC 04-115
*******************************************************************************/
package org.eclipse.ptp.debug.internal.core.pdi.model;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.ptp.debug.core.pdi.IPDILocator;
import org.eclipse.ptp.debug.core.pdi.IPDISession;
import org.eclipse.ptp.debug.core.pdi.PDIException;
import org.eclipse.ptp.debug.core.pdi.SessionObject;
import org.eclipse.ptp.debug.core.pdi.manager.IPDIRegisterManager;
import org.eclipse.ptp.debug.core.pdi.manager.IPDIVariableManager;
import org.eclipse.ptp.debug.core.pdi.model.IPDIStackFrame;
import org.eclipse.ptp.debug.core.pdi.model.IPDIStackFrameDescriptor;
import org.eclipse.ptp.debug.core.pdi.model.IPDITarget;
import org.eclipse.ptp.debug.core.pdi.model.IPDIThread;
import org.eclipse.ptp.debug.core.pdi.model.IPDIThreadStorage;
import org.eclipse.ptp.debug.core.pdi.model.IPDIThreadStorageDescriptor;
import org.eclipse.ptp.debug.core.pdi.request.IPDIGetStackInfoDepthRequest;
import org.eclipse.ptp.debug.core.pdi.request.IPDIListStackFramesRequest;
import org.eclipse.ptp.debug.core.pdi.request.IPDISetCurrentStackFrameRequest;
/**
* @author clement
*
*/
public class Thread extends SessionObject implements IPDIThread {
private static IPDIStackFrame[] noStack = new IPDIStackFrame[0];
private int id;
private String name;
private IPDIStackFrame currentFrame = null;
private List<IPDIStackFrame> currentFrames = null;
private int stackdepth = 0;
private IPDITarget target = null;
public Thread(IPDISession session, IPDITarget target, int threadId) {
this(session, target, threadId, null);
}
public Thread(IPDISession session, IPDITarget target, int threadId, String threadName) {
super(session, target.getTasks());
this.id = threadId;
this.name = threadName;
this.target = target;
}
/**
*
*/
public void clearState() {
stackdepth = 0;
currentFrame = null;
currentFrames = null;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#createThreadStorage(org.eclipse.ptp.debug.core.pdi.model.IPDIThreadStorageDescriptor)
*/
public IPDIThreadStorage createThreadStorage(IPDIThreadStorageDescriptor varDesc) throws PDIException {
if (varDesc instanceof ThreadStorageDescriptor) {
IPDIVariableManager varMgr = session.getVariableManager();
return varMgr.createThreadStorage((ThreadStorageDescriptor)varDesc);
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#equals(org.eclipse.ptp.debug.core.pdi.model.IPDIThread)
*/
public boolean equals(IPDIThread thread) {
if (thread instanceof Thread) {
Thread pthread = (Thread) thread;
return id == pthread.getId();
}
return super.equals(thread);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#getCurrentStackFrame()
*/
public IPDIStackFrame getCurrentStackFrame() throws PDIException {
if (currentFrame == null) {
IPDIStackFrame[] frames = getStackFrames(0, 0);
if (frames.length > 0) {
currentFrame = (StackFrame)frames[0];
}
}
return currentFrame;
}
/**
* @return
*/
public int getId() {
return id;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#getStackFrameCount()
*/
public int getStackFrameCount() throws PDIException {
if (stackdepth == 0) {
Target target = (Target)getTarget();
IPDIThread currentThread = (IPDIThread)target.getCurrentThread();
target.lockTarget();
try {
target.setCurrentThread(this, false);
IPDIGetStackInfoDepthRequest request = session.getRequestFactory().getGetStackInfoDepthRequest(getTasks());
session.getEventRequestManager().addEventRequest(request);
stackdepth = request.getDepth(getTasks());
}
finally {
target.setCurrentThread(currentThread, false);
target.releaseTarget();
}
}
return stackdepth;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#getStackFrames()
*/
public IPDIStackFrame[] getStackFrames() throws PDIException {
int depth = getStackFrameCount();
// refresh if we have nothing or if we have just a subset get everything.
if (currentFrames == null || currentFrames.size() < depth) {
currentFrames = new ArrayList<IPDIStackFrame>();
Target target = (Target)getTarget();
IPDIThread currentThread = (IPDIThread)target.getCurrentThread();
target.lockTarget();
try {
target.setCurrentThread(this, false);
IPDIListStackFramesRequest request = session.getRequestFactory().getListStackFramesRequest(session, getTasks());
session.getEventRequestManager().addEventRequest(request);
IPDIStackFrameDescriptor[] frames = request.getStackFrames(getTasks());
for (IPDIStackFrameDescriptor frame : frames) {
IPDILocator locator = frame.getLocator();
currentFrames.add(session.getModelFactory().newStackFrame(session, this, depth - frame.getLevel(),
locator.getFile(), locator.getFunction(), locator.getLineNumber(), locator.getAddress()));
}
} finally {
target.setCurrentThread(currentThread, false);
target.releaseTarget();
}
// assign the currentFrame if it was not done yet.
if (currentFrame == null) {
for (int i = 0; i < currentFrames.size(); i++) {
IPDIStackFrame stack = (IPDIStackFrame) currentFrames.get(i);
if (stack.getLevel() == depth) {
currentFrame = (StackFrame)stack;
}
}
}
}
return (IPDIStackFrame[]) currentFrames.toArray(noStack);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#getStackFrames(int, int)
*/
public IPDIStackFrame[] getStackFrames(int low, int high) throws PDIException {
if (currentFrames == null || currentFrames.size() < high) {
currentFrames = new ArrayList<IPDIStackFrame>();
Target target = (Target)getTarget();
IPDIThread currentThread = target.getCurrentThread();
target.lockTarget();
try {
target.setCurrentThread(this, false);
int depth = getStackFrameCount();
int upperBound;
if (high < depth) {
upperBound = Math.min(depth, STACKFRAME_DEFAULT_DEPTH);
}
else {
upperBound = depth;
}
IPDIListStackFramesRequest request = session.getRequestFactory().getListStackFramesRequest(session,
getTasks(), 0, upperBound);
session.getEventRequestManager().addEventRequest(request);
IPDIStackFrameDescriptor[] frames = request.getStackFrames(getTasks());
for (IPDIStackFrameDescriptor frame : frames) {
IPDILocator locator = frame.getLocator();
currentFrames.add(session.getModelFactory().newStackFrame(session, this, depth - frame.getLevel(),
locator.getFile(), locator.getFunction(), locator.getLineNumber(), locator.getAddress()));
}
} finally {
target.setCurrentThread(currentThread, false);
target.releaseTarget();
}
if (currentFrame == null) {
for (int i=0; i<currentFrames.size(); i++) {
StackFrame f = (StackFrame)currentFrames.get(i);
if (f.getLevel() == 0) {
currentFrame = f;
}
}
}
}
List<IPDIStackFrame> list = ((high - low + 1) <= currentFrames.size()) ? currentFrames.subList(low, high + 1) : currentFrames;
return (IPDIStackFrame[])list.toArray(noStack);
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#getTarget()
*/
public IPDITarget getTarget() {
return target;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#getThreadStorageDescriptors()
*/
public IPDIThreadStorageDescriptor[] getThreadStorageDescriptors() throws PDIException {
IPDIVariableManager varMgr = session.getVariableManager();
return varMgr.getThreadStorageDescriptors(this);
}
public void setCurrentStackFrame(IPDIStackFrame stackframe) throws PDIException {
currentFrame = stackframe;
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.pdi.model.IPDIThread#setCurrentStackFrame(org.eclipse.ptp.debug.core.pdi.model.IPDIStackFrame, boolean)
*/
public void setCurrentStackFrame(IPDIStackFrame stackframe, boolean doUpdate) throws PDIException {
int frameLevel = 0;
if (stackframe != null) {
frameLevel = stackframe.getLevel();
}
// Check to see if we are already at this level
if (currentFrame != null && currentFrame.getLevel() == frameLevel) {
if (stackframe != null) {
Thread aThread = (Thread)stackframe.getThread();
if (aThread != null && aThread.getId() == getId()) {
return;
}
}
}
Target target = (Target)getTarget();
int level = getStackFrameCount() - frameLevel;
target.lockTarget();
try {
target.setCurrentThread(this, doUpdate);
IPDISetCurrentStackFrameRequest request = session.getRequestFactory().getSetCurrentStackFrameRequest(getTasks(), level);
session.getEventRequestManager().addEventRequest(request);
request.waitUntilCompleted(getTasks());
currentFrame = stackframe;
if (doUpdate) {
IPDIRegisterManager regMgr = session.getRegisterManager();
if (regMgr.isAutoUpdate()) {
regMgr.update(target.getTasks());
}
IPDIVariableManager varMgr = session.getVariableManager();
if (varMgr.isAutoUpdate()) {
varMgr.update(target.getTasks());
}
}
}
finally {
target.releaseTarget();
}
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
String str = Integer.toString(id);
if (name != null) {
str += " " + name;
}
return str;
}
/**
*
*/
public void updateState() {
try {
getCurrentStackFrame();
} catch (PDIException e) {}
}
}