From 2194b478428e42ca035426c342e5ace38af21eaa Mon Sep 17 00:00:00 2001
From: Ludovic Apvrille <ludovic.apvrille@telecom-paristech.fr>
Date: Thu, 7 Apr 2011 13:43:38 +0000
Subject: [PATCH] AVATAR: Update on code generator: hnadling of timed
 transitions + various bugs resolved

---
 executablecode/src/debug.c                    | 14 ++++-
 executablecode/src/debug.h                    |  3 +-
 executablecode/src/mytimelib.c                |  5 +-
 executablecode/src/random.c                   |  7 +++
 executablecode/src/request.c                  | 35 +++++++++++-
 executablecode/src/request.h                  |  5 +-
 executablecode/src/request_manager.c          | 53 +++++++++++++------
 src/avatartranslator/AvatarStateMachine.java  | 28 +++++++++-
 .../toexecutable/AVATAR2CPOSIX.java           | 39 +++++++++-----
 .../toexecutable/TaskFile.java                |  2 +-
 10 files changed, 156 insertions(+), 35 deletions(-)

diff --git a/executablecode/src/debug.c b/executablecode/src/debug.c
index c858d95c40..1f29fd044d 100644
--- a/executablecode/src/debug.c
+++ b/executablecode/src/debug.c
@@ -68,6 +68,16 @@ void debugMsg(char *msg) {
   }
 }
 
-void debugTime(struct timespec *ts) {
-  printf("DT> sec=%ld nsec=%ld", ts->tv_sec, ts->tv_nsec);
+void debug2Msg(char *name, char *msg) {
+  if (debug == DEBUG_OFF) {
+    return;
+  }
+
+  if ((name != NULL) && (msg != NULL)) {
+    printf("DT - %s -> %s\n", name, msg);
+  }
+}
+
+void debugTime(char *msg, struct timespec *ts) {
+  printf("DT> (-------t------->) %s sec=%ld nsec=%ld\n", msg, ts->tv_sec, ts->tv_nsec);
 }
diff --git a/executablecode/src/debug.h b/executablecode/src/debug.h
index 7ad45e039b..7e73f3ce91 100644
--- a/executablecode/src/debug.h
+++ b/executablecode/src/debug.h
@@ -11,7 +11,8 @@ void debugTwoInts(char *msg, int value1, int value2);
 void debugLong(char *msg, long value);
 void debugInt(char *msg, int value);
 void debugMsg(char *msg);
-void debugTime(struct timespec *ts);
+void debug2Msg(char *name, char* msg);
+void debugTime(char* msg, struct timespec *ts);
 
 #endif
 
diff --git a/executablecode/src/mytimelib.c b/executablecode/src/mytimelib.c
index aa0b0a928d..efbd575aeb 100644
--- a/executablecode/src/mytimelib.c
+++ b/executablecode/src/mytimelib.c
@@ -31,6 +31,7 @@ int isBefore(struct timespec *src1, struct timespec *src2) {
 }
 
 void minTime(struct timespec *src1, struct timespec *src2, struct timespec *dest) {
+  debugMsg("MIN TIME COMPUTATION");
   if (isBefore(src1,src2)) {
     dest->tv_nsec = src1->tv_nsec;
     dest->tv_sec = src1->tv_sec;
@@ -52,9 +53,11 @@ void waitFor(long minDelay, long maxDelay) {
   struct timespec tsret;
   int delay;
 
+  debugMsg("Computing random");
+
   delay = computeLongRandom(minDelay, maxDelay);
 
-  debugLong("random delay=", delay);
+  debugLong("Random delay=", delay);
 
   delayToTimeSpec(&tssrc, delay);
 
diff --git a/executablecode/src/random.c b/executablecode/src/random.c
index c2be322463..287b219dbd 100644
--- a/executablecode/src/random.c
+++ b/executablecode/src/random.c
@@ -9,11 +9,18 @@
 #include <math.h>
 
 int computeRandom(int min, int max) {
+  if (min == max) {
+    return min;
+  }
   return (rand() % (max - min)) + min;
 }
 
 long computeLongRandom(long min, long max) {
 
+  if (min == max) {
+    return min;
+  }
+
   long rand0 = (((long)(rand()))*powl(2, ((((sizeof(long)-2))*8)-1)));
   long rand1 = rand0 % (max - min);
   //debugLong("min=", min);
diff --git a/executablecode/src/request.c b/executablecode/src/request.c
index e207c42af9..c9d287f7be 100644
--- a/executablecode/src/request.c
+++ b/executablecode/src/request.c
@@ -27,6 +27,7 @@ void makeNewRequest(request *req, int ID, int type, int hasDelay, long minDelay,
 
   req->next = NULL;
   req->listOfRequests = NULL;
+  req->nextRequestInList = NULL;
   req->type = type;
   req->ID = ID;
   req->hasDelay = hasDelay;
@@ -43,6 +44,8 @@ void makeNewRequest(request *req, int ID, int type, int hasDelay, long minDelay,
   req->alreadyPending = 0;
   req->delayElapsed = 0;
 
+  req->relatedRequest = NULL;
+
 }
 
 
@@ -139,8 +142,9 @@ setOfRequests *newListOfRequests(pthread_cond_t *wakeupCondition, pthread_mutex_
   return list;
 }
 
-void fillListOfRequests(setOfRequests *list, pthread_cond_t *wakeupCondition, pthread_mutex_t *mutex) {
+void fillListOfRequests(setOfRequests *list, char *name, pthread_cond_t *wakeupCondition, pthread_mutex_t *mutex) {
   list->head = NULL;
+  list->owner = name;
   list->wakeupCondition = wakeupCondition;
   list->mutex = mutex;
 }
@@ -173,3 +177,32 @@ void addRequestToList(setOfRequests *list, request* req) {
   tmpreq->nextRequestInList = req;
   req->nextRequestInList = NULL;
 }
+
+void removeAllPendingRequestsFromPendingLists(request *req, int apartThisOne) {
+  setOfRequests *list = req->listOfRequests;
+  request *reqtmp;
+
+  if (list == NULL) {
+    return;
+  }
+
+  reqtmp = list->head;
+
+  while(reqtmp != NULL) {
+    debugInt("Considering request of type", reqtmp->type);
+      if (reqtmp->alreadyPending) {
+	if (reqtmp->type ==  RECEIVE_SYNC_REQUEST) {
+	  debugMsg("Removing request from inWaitQueue");
+	  reqtmp->syncChannel->inWaitQueue = removeRequestFromList(reqtmp->syncChannel->inWaitQueue, reqtmp);
+	  debugMsg("done");
+	}
+
+	if (reqtmp->type ==  SEND_SYNC_REQUEST) {
+	  debugMsg("Removing request from outWaitQueue");
+	  reqtmp->syncChannel->outWaitQueue = removeRequestFromList(reqtmp->syncChannel->outWaitQueue, reqtmp);
+	  debugMsg("done");
+	}
+      }
+    reqtmp = reqtmp->nextRequestInList;
+  }
+}
diff --git a/executablecode/src/request.h b/executablecode/src/request.h
index bbb6888f2f..1ab2fa2fcc 100644
--- a/executablecode/src/request.h
+++ b/executablecode/src/request.h
@@ -20,6 +20,7 @@ struct request;
 typedef struct timespec timespec;
 
 struct setOfRequests {
+  char* owner;
   struct request *head;
   timespec startTime;
   timespec completionTime;
@@ -37,6 +38,7 @@ struct request {
   struct request *next;
   struct setOfRequests* listOfRequests;
   struct request* nextRequestInList;
+  struct request* relatedRequest; // For synchro fro example
   struct syncchannel *syncChannel;
   struct asyncchannel *asyncChannel;
   int type;
@@ -72,6 +74,7 @@ void copyParameters(request *src, request *dst);
 setOfRequests *newListOfRequests(pthread_cond_t *wakeupCondition, pthread_mutex_t *mutex);
 void addRequestToList(setOfRequests *list, request* req);
 void clearListOfRequests(setOfRequests *list);
-void fillListOfRequests(setOfRequests *list, pthread_cond_t *wakeupCondition, pthread_mutex_t *mutex);
+void fillListOfRequests(setOfRequests *list, char *name, pthread_cond_t *wakeupCondition, pthread_mutex_t *mutex);
 
+void removeAllPendingRequestsFromPendingLists(request *req, int apartThisOne);
 #endif
diff --git a/executablecode/src/request_manager.c b/executablecode/src/request_manager.c
index 3582e5ddab..65d8eee732 100644
--- a/executablecode/src/request_manager.c
+++ b/executablecode/src/request_manager.c
@@ -38,7 +38,9 @@ void executeSendSyncTransaction(request *req) {
     cpt --;
   } 
 
-  req->syncChannel->inWaitQueue = removeRequestFromList(req->syncChannel->inWaitQueue, selectedReq);
+  // Remove all related request from list requests
+  //req->syncChannel->inWaitQueue = removeRequestFromList(req->syncChannel->inWaitQueue, selectedReq);
+  req->relatedRequest = selectedReq;
 
   // Select the selected request, and notify the information
   selectedReq->selected = 1;
@@ -66,6 +68,7 @@ void executeReceiveSyncTransaction(request *req) {
 
   while(currentReq != NULL) {
     cpt ++;
+    //debugInt("cpt", cpt);
     currentReq = currentReq->next;
   }
   cpt = random() % cpt;
@@ -75,7 +78,8 @@ void executeReceiveSyncTransaction(request *req) {
     cpt --;
   } 
 
-  req->syncChannel->outWaitQueue = removeRequestFromList(req->syncChannel->outWaitQueue, selectedReq);
+  //req->syncChannel->outWaitQueue = removeRequestFromList(req->syncChannel->outWaitQueue, selectedReq);
+  req->relatedRequest = selectedReq;
 
   // Select the request, and notify the information in the channel
   selectedReq->selected = 1;
@@ -104,18 +108,21 @@ int executable(setOfRequests *list, int nb) {
     if (!(req->delayElapsed)) {
       if (req->hasDelay) {
 	// Is the delay elapsed???
+	debugTime("begin time of list of request", &list->startTime);
+	debugTime("start time of this request", &req->myStartTime);
 	if (tsDone == 0) {
 	  clock_gettime(CLOCK_REALTIME, &ts);
+	  debugTime("Current time", &ts);
 	  tsDone = 1;
 	}
 
-	if (isBefore(&(req->myStartTime), &ts)) {
+	if (isBefore(&ts, &(req->myStartTime)) == 1) {
 	  // Delay not elapsed
 	  debugMsg("---------t--------> delay NOT elapsed");
 	  if (list->hasATimeRequest == 0) {
 	    list->hasATimeRequest = 1;
 	    list->minTimeToWait.tv_nsec = req->myStartTime.tv_nsec;
-	    list->minTimeToWait.tv_nsec = req->myStartTime.tv_nsec;
+	    list->minTimeToWait.tv_sec = req->myStartTime.tv_sec;
 	  } else {
 	    minTime(&(req->myStartTime), &(list->minTimeToWait),&(list->minTimeToWait));
 	  }
@@ -139,9 +146,12 @@ int executable(setOfRequests *list, int nb) {
 	debugMsg("Send sync");
 
 	if (req->syncChannel->inWaitQueue != NULL) {
+	  debugMsg("Send sync executable");
 	  req->executable = 1;
 	  cpt ++;
-	} 
+	}  else {
+	  debugMsg("Send sync not executable");
+	}
 	index ++;
       }
 
@@ -155,6 +165,7 @@ int executable(setOfRequests *list, int nb) {
       }
 
       if (req->type == IMMEDIATE) {
+	debugMsg("immediate");
 	req->executable = 1;
 	cpt ++;
       }
@@ -172,10 +183,12 @@ void private__makeRequestPending(setOfRequests *list) {
   while(req != NULL) {
     if ((req->delayElapsed) && (!(req->alreadyPending))) {
       if (req->type == SEND_SYNC_REQUEST) {
+	debugMsg("Adding pending request in outWaitqueue");
 	req->syncChannel->outWaitQueue = addToRequestQueue(req->syncChannel->outWaitQueue, req);
 	req->alreadyPending = 1;
       }
       if (req->type ==  RECEIVE_SYNC_REQUEST) {
+	debugMsg("Adding pending request in inWaitqueue");
 	req->alreadyPending = 1;
 	req->syncChannel->inWaitQueue = addToRequestQueue(req->syncChannel->inWaitQueue, req);
       }
@@ -195,6 +208,15 @@ void private__makeRequest(request *req) {
   }
 
   // IMMEDIATE: Nothing to do
+  
+  // In all cases: remove other requests of the same list from their pending form
+  debugMsg("Removing original req");
+  removeAllPendingRequestsFromPendingLists(req, 1);
+  if (req->relatedRequest != NULL) {
+    debugMsg("Removing related req");
+    removeAllPendingRequestsFromPendingLists(req->relatedRequest, 0);
+  }
+  
 }
 
 
@@ -283,7 +305,7 @@ void setLocalStartTime(setOfRequests *list) {
     if (req->hasDelay) {
       req->delayElapsed = 0;
       addTime(&(list->startTime), &(req->delay), &(req->myStartTime));
-      debugMsg(" -----t------>: Request with delay");
+      debug2Msg(list->owner, " -----t------>: Request with delay");
     } else {
       req->delayElapsed = 1;
       req->myStartTime.tv_nsec = list->startTime.tv_nsec;
@@ -303,30 +325,31 @@ request *executeListOfRequests(setOfRequests *list) {
   setLocalStartTime(list);
   
   // Try to find a request that could be executed
-  debugMsg("Locking mutex");
+  debug2Msg(list->owner, "Locking mutex");
   pthread_mutex_lock(list->mutex);
-  debugMsg("Mutex locked");
+  debug2Msg(list->owner, "Mutex locked");
 
-  debugMsg("Going to execute request");
+  debug2Msg(list->owner, "Going to execute request");
 
   while((req = private__executeRequests(list)) == NULL) {
-    debugMsg("Waiting for request!");
+    debug2Msg(list->owner, "Waiting for request!");
     if (list->hasATimeRequest == 1) {
-      debugMsg("Waiting for a request and at most for a given time");
+      debug2Msg(list->owner, "Waiting for a request and at most for a given time");
+      debugTime("Min time to wait=", &(list->minTimeToWait));
       pthread_cond_timedwait(list->wakeupCondition, list->mutex, &(list->minTimeToWait));
     } else {
-      debugMsg("Releasing mutex");
+      debug2Msg(list->owner, "Releasing mutex");
       pthread_cond_wait(list->wakeupCondition, list->mutex);
     }
-    debugMsg("Waking up for requests! -> getting mutex");
+    debug2Msg(list->owner, "Waking up for requests! -> getting mutex");
   }
 
-  debugMsg("Request selected!");
+  debug2Msg(list->owner, "Request selected!");
 
   clock_gettime(CLOCK_REALTIME, &list->completionTime);
 
   pthread_mutex_unlock(list->mutex); 
-  debugMsg("Mutex unlocked");
+  debug2Msg(list->owner, "Mutex unlocked");
   return req;
 }
 
diff --git a/src/avatartranslator/AvatarStateMachine.java b/src/avatartranslator/AvatarStateMachine.java
index b953194601..0c5a61bb71 100644
--- a/src/avatartranslator/AvatarStateMachine.java
+++ b/src/avatartranslator/AvatarStateMachine.java
@@ -266,13 +266,16 @@ public class AvatarStateMachine extends AvatarElement {
 		AvatarState as;
 		AvatarTransition at;
 		LinkedList<AvatarStateMachineElement> ll;
+		String tmp;
 		
 		// It cannot be a start / stop state since they have been previously removed ..
 		if (_element instanceof AvatarActionOnSignal) {
 			ll = getPreviousElementsOf(_element);
 			for(AvatarStateMachineElement element: ll) {
 				if (element instanceof AvatarTransition) {
-					as = new AvatarState("internalstate", null);
+					tmp = findUniqueStateName("internalstate__");
+					TraceManager.addDev("Creating state with name=" + tmp);
+					as = new AvatarState(tmp, null);
 					element.removeNext(_element);
 					element.addNext(as);
 					at = new AvatarTransition("internaltransition", null);
@@ -712,5 +715,28 @@ public class AvatarStateMachine extends AvatarElement {
 			replace(ass, astate);
 		}
 	}
+	
+	
+	public String findUniqueStateName(String name) {
+		int id = 0;
+		boolean found;
+		
+		while(id < 10000) {
+			found = false;
+			for(AvatarStateMachineElement elt: elements) {
+				if (elt instanceof AvatarState) {
+					if (elt.getName().compareTo(name+id) == 0) {
+						found = true;
+						break;
+					}
+				}
+			}
+			if (!found) {
+					return name + id;
+				}
+			id ++;
+		}
+		return name + id;
+	}
 
 }
diff --git a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java
index 273ee45a9a..a36fef9de1 100755
--- a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java
+++ b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java
@@ -118,6 +118,9 @@ public class AVATAR2CPOSIX {
 		mainFile = new MainFile("main");
 		taskFiles = new Vector<TaskFile>();
 		
+		avspec.removeCompositeStates();
+		avspec.removeTimers();
+		
 		makeMainMutex();
 	
 		makeSynchronousChannels();
@@ -219,7 +222,7 @@ public class AVATAR2CPOSIX {
 				cpt ++;
 			}
 			
-			ret += ") {" + CR + "debugMsg(\"-> ....() Entering method " + am.getName() + "\");" + CR;
+			ret += ") {" + CR + "debugMsg(\"-> ....() Executing method " + am.getName() + "\");" + CR;
 			
 			list = am.getListOfAttributes();
 			cpt = 0;
@@ -265,7 +268,7 @@ public class AVATAR2CPOSIX {
 		
 		s+= CR + "char * __myname = (char *)arg;" + CR;
 		
-		s+= CR + "fillListOfRequests(&__list, &__myCond, &__mainMutex);" + CR; 
+		s+= CR + "fillListOfRequests(&__list, __myname, &__myCond, &__mainMutex);" + CR; 
 		
 		s+= "printf(\"my name = %s\\n\", __myname);" + CR;
 		
@@ -320,7 +323,7 @@ public class AVATAR2CPOSIX {
 				String g = modifyGuard(at.getGuard());
 				
 				ret += "if (!" + g + ") {" + CR;
-				ret += "debugMsg(\"Guard failed: " + g + "\");" + CR;
+				ret += "debug2Msg(__myname, \"Guard failed: " + g + "\");" + CR;
 				ret += "__currentState = STATE__STOP__STATE;" + CR; 
 				ret += "break;" + CR;
 				ret += "}" + CR;
@@ -338,7 +341,7 @@ public class AVATAR2CPOSIX {
 	
 		if (_asme instanceof AvatarState) {
 			if (!firstCall) {
-				ret += "debugMsg(\"-> (=====) Entering state + " + _asme.getName() + "\");" + CR;
+				ret += "debug2Msg(__myname, \"-> (=====) Entering state + " + _asme.getName() + "\");" + CR;
 				return ret + "__currentState = STATE__" + _asme.getName() + ";" + CR; 
 			} else {
 				if (_asme.nbOfNexts() == 0) {
@@ -374,7 +377,7 @@ public class AVATAR2CPOSIX {
 				// Make all requests
 				// Test if at least one request in the list!
 				ret += "if (nbOfRequests(&__list) == 0) {" + CR;
-				ret += "debugMsg(\"No possible request\");" + CR;
+				ret += "debug2Msg(__myname, \"No possible request\");" + CR;
 				ret += "__currentState = STATE__STOP__STATE;" + CR; 
 				ret += "break;" + CR;
 				ret += "}" + CR;
@@ -421,7 +424,7 @@ public class AVATAR2CPOSIX {
 		
 		if (_asme instanceof AvatarActionOnSignal) {
 			AvatarActionOnSignal aaos = (AvatarActionOnSignal)_asme;
-			ret += makeSignalAction(aaos, 0);
+			ret += makeSignalAction(aaos, 0, false, "", "");
 			AvatarSignal as = aaos.getSignal();
 			AvatarRelation ar = avspec.getAvatarRelationWithSignal(as);
 			ret += executeOneRequest("__req0");
@@ -446,7 +449,11 @@ public class AVATAR2CPOSIX {
 			ret += "if (" + g + ") {" + CR;
 		}
 		
-		ret += makeSignalAction(aaos, _index);
+		if (_at.hasDelay()) {
+			ret += makeSignalAction(aaos, _index, true, _at.getMinDelay(), _at.getMaxDelay());
+		} else {
+			ret += makeSignalAction(aaos, _index, false, "", "");
+		}
 		ret += "addRequestToList(&__list, &__req" + _index + ");" + CR;
 		
 		if (_at.isGuarded()) {
@@ -456,13 +463,21 @@ public class AVATAR2CPOSIX {
 		return ret;
 	}
 	
-	private String makeSignalAction(AvatarActionOnSignal _aaos, int _index) {
+	private String makeSignalAction(AvatarActionOnSignal _aaos, int _index, boolean hasDelay, String minDelay, String maxDelay) {
 		String ret = "";
 		int i;
 		
 		AvatarSignal as = _aaos.getSignal();
 		AvatarRelation ar = avspec.getAvatarRelationWithSignal(as);
 		
+		String delay;
+		
+		if (hasDelay) {
+			delay = "1, " + reworkDelay(minDelay) + ", " + reworkDelay(maxDelay);
+		} else {
+			delay = "0, 0, 0";
+		}
+		
 		if (ar != null) {
 			
 			// Sending
@@ -472,10 +487,10 @@ public class AVATAR2CPOSIX {
 					ret += "__params" + _index + "[" + i + "] = &" +  _aaos.getValue(i) + ";" + CR;
 				}
 				if (ar.isAsynchronous()) {
-					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", SEND_ASYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
+					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", SEND_ASYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
 					ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR;
 				} else {
-					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_SYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
+					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_SYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
 					ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR;
 				}
 				
@@ -485,10 +500,10 @@ public class AVATAR2CPOSIX {
 					ret += "__params" + _index + "[" + i + "] = &" +  _aaos.getValue(i) + ";" + CR;
 				}
 				if (ar.isAsynchronous()) {
-					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_ASYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
+					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_ASYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
 					ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR;
 				} else {
-					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_SYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
+					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_SYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
 					ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR;
 				}
 			}
diff --git a/src/avatartranslator/toexecutable/TaskFile.java b/src/avatartranslator/toexecutable/TaskFile.java
index 36c602ac52..c2ba1c58d9 100755
--- a/src/avatartranslator/toexecutable/TaskFile.java
+++ b/src/avatartranslator/toexecutable/TaskFile.java
@@ -54,7 +54,7 @@ import avatartranslator.*;
 public class TaskFile {
 
 	private final static String INCLUDE_HEADER = "#include <stdio.h>\n#include <pthread.h>\n#include <unistd.h>\n#include <stdlib.h>\n";
-	private final static String LOCAL_INCLUDE_HEADER = "#include \"request.h\"\n#include \"syncchannel.h\"\n#include \"request_manager.h\"\n#include \"debug.h\"\n#include \"defs.h\"\n#include \"mytimelib.h\"\n#include \"main.h\""; 
+	private final static String LOCAL_INCLUDE_HEADER = "#include \"request.h\"\n#include \"syncchannel.h\"\n#include \"request_manager.h\"\n#include \"debug.h\"\n#include \"defs.h\"\n#include \"mytimelib.h\"\n#include \"random.h\"\n#include \"main.h\""; 
 	
 	private final static String CR = "\n";
 	
-- 
GitLab