/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.backend.java.debugging;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Semaphore;
import abs.backend.java.lib.runtime.ABSException;
import abs.backend.java.lib.types.ABSValue;
import abs.backend.java.observing.COGView;
import abs.backend.java.observing.FutView;
import abs.backend.java.observing.GuardView;
import abs.backend.java.observing.ObjectView;
import abs.backend.java.observing.TaskObserver;
import abs.backend.java.observing.TaskSchedulerObserver;
import abs.backend.java.observing.TaskStackFrameView;
import abs.backend.java.observing.TaskView;
public class DebugModel implements TaskObserver, TaskSchedulerObserver {
final Map<TaskView, TaskInfo> taskToLineMap = new HashMap<TaskView, TaskInfo>();
final Map<COGView, COGInfo> cogInfo = new HashMap<COGView, COGInfo>();
final ArrayList<DebugModelListener> listener = new ArrayList<DebugModelListener>();
final Set<TaskView> steppingTasks = new HashSet<TaskView>();
public COGInfo getCOGInfo(COGView view) {
return cogInfo.get(view);
}
public synchronized TaskInfo getTaskInfo(TaskView task) {
return taskToLineMap.get(task);
}
public synchronized Semaphore getSema(TaskView info) {
return taskToLineMap.get(info).stepSema;
}
public void stepTask(TaskView task) {
getSema(task).release();
}
public void cogCreated(COGView cog, ObjectView initialObject) {
cog.getScheduler().registerTaskSchedulerObserver(this);
ArrayList<DebugModelListener> localList;
COGInfo info = new COGInfo(cog, initialObject);
synchronized (this) {
cogInfo.put(cog, info);
localList = new ArrayList<DebugModelListener>(listener);
}
for (DebugModelListener l : localList) {
l.cogCreated(info);
}
}
public synchronized TaskInfo addInfoLine(TaskView task) {
TaskInfo line = new TaskInfo(task);
taskToLineMap.put(task, line);
for (DebugModelListener l : listener) {
l.taskInfoAdded(line);
}
return line;
}
public void updateInfoLine(TaskView task, TaskInfo line) {
ArrayList<DebugModelListener> localList;
synchronized (this) {
taskToLineMap.put(task, line);
localList = new ArrayList<DebugModelListener>(listener);
}
for (DebugModelListener l : localList) {
l.taskInfoChanged(line);
}
}
public synchronized void removeInfoLine(TaskView task) {
TaskInfo line = taskToLineMap.remove(task);
for (DebugModelListener l : listener) {
l.taskInfoRemoved(line);
}
}
public synchronized void registerListener(DebugModelListener l) {
listener.add(l);
}
@Override
public synchronized void taskCreated(TaskView task) {
steppingTasks.add(task);
task.registerTaskListener(this);
TaskInfo info = addInfoLine(task);
COGInfo cinfo = cogInfo.get(task.getCOG());
cinfo.addTask(info);
cogInfoChanged(cinfo);
}
private synchronized void cogInfoChanged(COGInfo info) {
for (DebugModelListener l : listener) {
l.cogChanged(info);
}
}
@Override
public synchronized void taskSuspended(TaskView task, GuardView guard) {
updateTaskState(task, TaskState.SUSPENDED, guard, null);
}
@Override
public synchronized void taskStarted(TaskView task) {
updateTaskState(task, TaskState.RUNNING, null, null);
}
@Override
public synchronized void taskDeadlocked(TaskView task) {
updateTaskState(task, TaskState.DEADLOCKED, null, null);
}
@Override
public synchronized void taskFinished(TaskView task) {
TaskState newState = TaskState.FINISHED;
if (task.hasException()) {
ABSException e = task.getException();
if (e.isAssertion()) {
newState = TaskState.ASSERTION_FAILED;
} else {
newState = TaskState.EXCEPTION;
}
}
updateTaskState(task, newState, null, null);
}
@Override
public synchronized void taskBlockedOnFuture(TaskView task, FutView fut) {
updateTaskState(task, TaskState.BLOCKED, null, fut);
}
@Override
public void taskRunningAfterWaiting(TaskView task, FutView fut) {
updateTaskState(task, TaskState.RUNNING, null, null);
}
@Override
public void taskResumed(TaskView task, GuardView view) {
updateTaskState(task, TaskState.RUNNING, null, null);
}
@Override
public void taskReady(TaskView task) {
updateTaskState(task, TaskState.READY, null, null);
}
private void updateTaskState(TaskView task, TaskState state, GuardView guard, FutView fut) {
synchronized (this) {
TaskInfo info = getTaskInfo(task);
if (state == TaskState.RUNNING) {
if (info.isStepping) {
steppingTasks.add(task);
}
} else {
steppingTasks.remove(task);
}
info.state = state;
info.waitingOnGuard = guard;
info.blockedOnFuture = fut;
updateInfoLine(task, info);
}
}
private void waitForClick(TaskView task) {
try {
System.out.println("Task " + task.getID() + " waiting for click...");
if (getTaskInfo(task).isStepping)
getSema(task).acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void taskStep(TaskView task, String fileName, int line) {
synchronized (this) {
TaskInfo info = getTaskInfo(task);
info.updateLine(line);
info.updateFile(fileName);
info.state = TaskState.RUNNING;
updateInfoLine(task, info);
}
// waitForClick(task);
}
public synchronized void stepRandom() {
stepTask(steppingTasks.iterator().next());
}
public synchronized void runTask(TaskView task) {
steppingTasks.remove(task);
getTaskInfo(task).isStepping = false;
getSema(task).release();
}
//New Methods
public List<COGView> getCOGs(){
List<COGView> cogs = new ArrayList<COGView>();
cogs.addAll(cogInfo.keySet());
return cogs;
}
public List<COGInfo> getCOGInfos(){
List<COGInfo> cogInfos = new ArrayList<COGInfo>();
for(COGView cog : getCOGs()){
cogInfos.add(cogInfo.get(cog));
}
return cogInfos;
}
public List<TaskInfo> getTaskInfos(COGView cog){
return cogInfo.get(cog).getTasks();
}
public List<TaskView> getTasks(COGView cog){
List<TaskView> tasks = new ArrayList<TaskView>();
for(TaskInfo taskInfo : getTaskInfos(cog)) {
tasks.add(taskInfo.getTaskView());
}
return tasks;
}
@Override
public void stackFrameCreated(TaskView task, TaskStackFrameView stackFrame) {
// TODO Auto-generated method stub
}
@Override
public void localVariableChanged(TaskStackFrameView stackFrame, String name, ABSValue v) {
// TODO Auto-generated method stub
}
@Override
public void stackFrameRemoved(TaskView task, TaskStackFrameView oldFrame) {
// TODO Auto-generated method stub
}
}