00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.calcium;
00032
00033 import java.io.Serializable;
00034 import java.util.Hashtable;
00035 import java.util.Iterator;
00036 import java.util.Vector;
00037
00038 import org.apache.log4j.Logger;
00039 import org.objectweb.proactive.calcium.interfaces.Instruction;
00040 import org.objectweb.proactive.calcium.statistics.StatsImpl;
00041 import org.objectweb.proactive.core.util.log.Loggers;
00042 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00043
00056 public class Task<T> implements Serializable, Comparable<Task>{
00057 static Logger logger = ProActiveLogger.getLogger(Loggers.SKELETONS);
00058
00059 public static int DEFAULT_PRIORITY=0;
00060 static private int DEFAULT_STREAM_ID,DEFAULT_ROOT_PARENT_ID=-1;
00061
00062
00063
00064 private int familyId;
00065 private int parentId;
00066 private T object;
00067 private int id;
00068 private int priority;
00069 private boolean isTainted;
00070 private boolean isDummy;
00071 private StatsImpl stats;
00072 private int streamId;
00073
00074
00075 private Vector<Instruction<T>> stack;
00076
00077
00078
00079
00080 private Vector<Task<T>> childrenReady;
00081 private Hashtable<Task<?>,Task<T>> childrenWaiting;
00082 private Vector<Task<T>> childrenFinished;
00083 private Exception exception;
00084
00085
00086 public Task(){
00087
00088 }
00089
00090 private Task(T object, int id, int priority, int parentId, int familyId, int streamId) {
00091 this.object = object;
00092 this.id = id;
00093 this.priority = priority;
00094 this.parentId= parentId;
00095 this.familyId=familyId;
00096 this.streamId=streamId;
00097
00098 isDummy=false;
00099 stats = new StatsImpl();
00100 stack=new Vector<Instruction<T>>();
00101
00102 childrenReady=new Vector<Task<T>>();
00103 childrenWaiting=new Hashtable<Task<?>,Task<T>>();
00104 childrenFinished=new Vector<Task<T>>();
00105 exception=null;
00106 }
00107
00108 public Task(T object){
00109 this(object, (int)(Math.random()*Integer.MAX_VALUE), DEFAULT_PRIORITY,
00110 DEFAULT_ROOT_PARENT_ID, DEFAULT_ROOT_PARENT_ID, DEFAULT_STREAM_ID);
00111 this.familyId=this.id;
00112 }
00113
00123 public Task<T> reBirth(T object){
00124 Task<T> newMe = new Task<T>(object,id, priority,parentId, familyId,streamId);
00125 newMe.setStack(this.stack);
00126
00127 newMe.isDummy=this.isDummy;
00128 newMe.isTainted=this.isTainted;
00129
00130 newMe.stats=this.stats;
00131
00132 return newMe;
00133 }
00134
00135 public int compareTo(Task task){
00136 return task.priority - this.priority;
00137 }
00138
00139 @Override
00140 public int hashCode(){
00141 return id;
00142 }
00143
00144
00145 public boolean equals(Task<T> task){
00146 return this.hashCode()==task.hashCode();
00147
00148 }
00149
00150 @Override
00151 public boolean equals(Object o){
00152 return this.hashCode() == o.hashCode();
00153 }
00154
00161 public Vector<Instruction<T>> getStack(){
00162 return getVector(stack);
00163 }
00164
00171 public void setStack(Vector<Instruction<T>> v){
00172 setVector(stack, v);
00173 }
00174
00175 private <E> Vector<E> getVector(Vector<E> vector){
00176
00177 Iterator<E> it = vector.iterator();
00178
00179 Vector<E> v = new Vector<E>();
00180 while(it.hasNext()){
00181 v.add(it.next());
00182 }
00183 return v;
00184 }
00185
00186 private <E> void setVector(Vector<E> oldVector, Vector<E> newVector){
00187 oldVector.clear();
00188
00189 Iterator<E> it = newVector.iterator();
00190 while(it.hasNext()){
00191 oldVector.add(it.next());
00192 }
00193 }
00194
00198 public int getParentId() {
00199 return parentId;
00200 }
00201
00205 private void setParent(int parentId) {
00206 this.parentId = parentId;
00207 }
00208
00209 private void setFamily(int familyId) {
00210 this.familyId=familyId;
00211 }
00212
00213 public boolean hasInstruction(){
00214 return !stack.isEmpty();
00215 }
00216
00217 public boolean hasReadyChildTask(){
00218 return !childrenReady.isEmpty();
00219 }
00220
00221 public Instruction<T> popInstruction(){
00222
00223 Instruction<T> c = stack.remove(stack.size()-1);
00224
00225 return c;
00226 }
00227
00228 public Instruction<T> peekInstruction(){
00229
00230 return stack.get(stack.size()-1);
00231 }
00232
00233 public void pushInstruction(Instruction<T> inst){
00234 stack.add(inst);
00235 }
00236
00237 public T getObject(){
00238 return object;
00239 }
00240
00241 public void setObject(T object){
00242 this.object=object;
00243 }
00244
00248 public int getId() {
00249 return id;
00250 }
00251
00255 public int getPriority() {
00256 return priority;
00257 }
00258
00259 public void setPriority(int newPriority) {
00260 this.priority=newPriority;
00261 }
00262
00269 public synchronized Task<T> getReadyChild(){
00270
00271 if(childrenReady.isEmpty()) return null;
00272
00273 Task<T> task=this.childrenReady.remove(0);
00274 this.childrenWaiting.put(task, task);
00275 return task;
00276 }
00277
00284 public synchronized void addReadyChild(Task<T> child){
00285 child.setPriority(getPriority()+1);
00286 child.setParent(getId());
00287 child.setFamily(getFamilyId());
00288 this.childrenReady.add(child);
00289 }
00290
00291 @SuppressWarnings("unchecked")
00292 public synchronized boolean setFinishedChild(Task<?> task){
00293
00294 if(!task.isFinished()){
00295 logger.error("Task id="+task+" claims to be unfinished.");
00296 return false;
00297 }
00298
00299 if(task.getParentId()!=this.getId()) {
00300 logger.error("Setting other task's child as my child: child.id="+" task.parent.id="+task.parentId);
00301 return false;
00302 }
00303
00304 if(!this.childrenWaiting.containsKey(task)){
00305 logger.error("Parent id="+this.id+" not waiting for child: task.id="+task.id);
00306 return false;
00307 }
00308
00309 childrenWaiting.remove(task);
00310 childrenFinished.add((Task<T>)task);
00311
00312 stats.addChildStats(task.getStats());
00313
00314 return true;
00315 }
00316
00317 public synchronized boolean isFinished(){
00318 return isReady() && !hasInstruction();
00319 }
00320
00321 public synchronized boolean isReady(){
00322 return childrenReady.isEmpty() &&
00323 childrenWaiting.isEmpty();
00324 }
00325
00326
00327 public synchronized boolean hasFinishedChild(){
00328 return !this.childrenFinished.isEmpty();
00329 }
00330
00331 public synchronized Task<T> getFinishedChild(){
00332
00333 if(childrenFinished.isEmpty()){
00334 logger.error("No finished child available");
00335 return null;
00336 }
00337
00338 return childrenFinished.remove(0);
00339 }
00340
00341 public boolean isRootTask(){
00342 return this.familyId==this.id;
00343 }
00344
00345 @Override
00346 public String toString(){
00347 return this.familyId+"/"+parentId+"."+this.id;
00348 }
00349
00350 public boolean isDummy() {
00351 return isDummy;
00352 }
00353
00354 public void setDummy() {
00355 isDummy=true;
00356 }
00357
00361 public Exception getException() {
00362 return exception;
00363 }
00364
00368 public void setException(Exception exception) {
00369 this.exception = exception;
00370 }
00371
00372 public boolean hasException(){
00373 return this.exception !=null;
00374 }
00375
00379 public int getFamilyId() {
00380 return familyId;
00381 }
00382
00386 public boolean isTainted() {
00387 return isTainted;
00388 }
00389
00393 public void setTainted(boolean isTainted) {
00394 this.isTainted = isTainted;
00395 }
00396
00397 public void markFinishTime(){
00398 stats.markFinishTime();
00399 }
00400
00401 public StatsImpl getStats(){
00402 return stats;
00403 }
00404
00408 public int getStreamId() {
00409 return streamId;
00410 }
00411
00415 public void setStreamId(int streamId) {
00416 this.streamId = streamId;
00417 }
00418 }