From 29c21b68cbb4739525ad429589a289f147354328 Mon Sep 17 00:00:00 2001
From: Ludovic Apvrille <ludovic.apvrille@telecom-paristech.fr>
Date: Tue, 5 Apr 2011 15:59:55 +0000
Subject: [PATCH] AVATAR code generator: Support for time, but still buggy

---
 executablecode/Makefile                       |   2 +-
 executablecode/Makefile.src                   |   2 +-
 executablecode/src/debug.c                    |  10 +
 executablecode/src/debug.h                    |   1 +
 executablecode/src/defs.h                     |   1 +
 executablecode/src/mytimelib.c                |  64 ++++++
 executablecode/src/mytimelib.h                |  13 ++
 executablecode/src/random.c                   |  16 +-
 executablecode/src/random.h                   |   2 +-
 executablecode/src/request.c                  |  27 ++-
 executablecode/src/request.h                  |  23 ++-
 executablecode/src/request_manager.c          | 189 ++++++++++--------
 executablecode/src/request_manager.h          |   3 -
 .../toexecutable/AVATAR2CPOSIX.java           |  43 +++-
 .../toexecutable/TaskFile.java                |   2 +-
 ...JDialogAvatarExecutableCodeGeneration.java |  17 +-
 16 files changed, 306 insertions(+), 109 deletions(-)
 create mode 100644 executablecode/src/mytimelib.c
 create mode 100644 executablecode/src/mytimelib.h

diff --git a/executablecode/Makefile b/executablecode/Makefile
index dda10ddd96..d861ff0349 100755
--- a/executablecode/Makefile
+++ b/executablecode/Makefile
@@ -20,7 +20,7 @@ OBJDIR = lib
 MODULE = run
 SRCS_generated_DIR = generated_src/
 include Makefile.src
-SRCS_base = src/request.c src/message.c src/myerrors.c src/debug.c src/syncchannel.c src/asyncchannel.c src/request_manager.c src/random.c
+SRCS_base = src/request.c src/message.c src/myerrors.c src/debug.c src/syncchannel.c src/asyncchannel.c src/request_manager.c src/random.c src/mytimelib.c
 SRCS_base_DIR = .
 SRCS_base_DIRSRC = src/ 
 OBJS_executor = $(SRCS_base:%.c=lib/%.o)
diff --git a/executablecode/Makefile.src b/executablecode/Makefile.src
index a76db044da..e44f354179 100755
--- a/executablecode/Makefile.src
+++ b/executablecode/Makefile.src
@@ -1 +1 @@
-SRCS = generated_src/main.c generated_src/Block2.c generated_src/Block1.c generated_src/Block0.c 
\ No newline at end of file
+SRCS = generated_src/main.c generated_src/Block1.c generated_src/Block0.c 
\ No newline at end of file
diff --git a/executablecode/src/debug.c b/executablecode/src/debug.c
index 373f09fbae..52342d78f5 100644
--- a/executablecode/src/debug.c
+++ b/executablecode/src/debug.c
@@ -46,6 +46,16 @@ void debugInt(char *msg, int value) {
   }
 }
 
+void debugLong(char *msg, long value) {
+  if (debug == DEBUG_OFF) {
+    return;
+  }
+  
+  if (msg != NULL) {
+    printf("DT> %s: %ld\n", msg, value);
+  }
+}
+
 void debugMsg(char *msg) {
   if (debug == DEBUG_OFF) {
     return;
diff --git a/executablecode/src/debug.h b/executablecode/src/debug.h
index 941ac6babf..f8fb933d27 100644
--- a/executablecode/src/debug.h
+++ b/executablecode/src/debug.h
@@ -8,6 +8,7 @@ void unactiveDebug();
 
 void debugThreeInts(char *msg, int value1, int value2, int value3);
 void debugTwoInts(char *msg, int value1, int value2);
+void debugLong(char *msg, long value);
 void debugInt(char *msg, int value);
 void debugMsg(char *msg);
 
diff --git a/executablecode/src/defs.h b/executablecode/src/defs.h
index 9dc1a0994b..3b997bfdf8 100644
--- a/executablecode/src/defs.h
+++ b/executablecode/src/defs.h
@@ -5,4 +5,5 @@
 #define true 1
 #define false 0
 
+
 #endif
diff --git a/executablecode/src/mytimelib.c b/executablecode/src/mytimelib.c
new file mode 100644
index 0000000000..aa0b0a928d
--- /dev/null
+++ b/executablecode/src/mytimelib.c
@@ -0,0 +1,64 @@
+#include<time.h>
+
+#include "mytimelib.h"
+#include "random.h"
+#include "debug.h"
+
+void addTime(struct timespec *src1, struct timespec *src2, struct timespec *dest) {
+  dest->tv_nsec = src1->tv_nsec + src2->tv_nsec;
+  dest->tv_sec = src1->tv_sec + src2->tv_sec;
+  if (dest->tv_nsec > 1000000000) {
+    dest->tv_sec = dest->tv_sec + (dest->tv_nsec / 1000000000);
+    dest->tv_nsec = dest->tv_nsec % 1000000000;
+  }
+
+}
+
+int isBefore(struct timespec *src1, struct timespec *src2) {
+  if (src1->tv_sec > src2->tv_sec) {
+    return 0;
+  }
+
+  if (src1->tv_sec < src2->tv_sec) {
+    return 1;
+  }
+
+  if (src1->tv_nsec < src2->tv_nsec) {
+    return 1;
+  }
+
+  return 0;
+}
+
+void minTime(struct timespec *src1, struct timespec *src2, struct timespec *dest) {
+  if (isBefore(src1,src2)) {
+    dest->tv_nsec = src1->tv_nsec;
+    dest->tv_sec = src1->tv_sec;
+  } else {
+    dest->tv_nsec = src2->tv_nsec;
+    dest->tv_sec = src2->tv_sec;
+  }
+  
+}
+
+
+void delayToTimeSpec(struct timespec *ts, long delay) {
+  ts->tv_nsec = (delay % 1000000)*1000;
+  ts->tv_sec = (delay / 1000000);
+}
+
+void waitFor(long minDelay, long maxDelay) {
+  struct timespec tssrc;
+  struct timespec tsret;
+  int delay;
+
+  delay = computeLongRandom(minDelay, maxDelay);
+
+  debugLong("random delay=", delay);
+
+  delayToTimeSpec(&tssrc, delay);
+
+  debugLong("............. waiting For", delay);
+  nanosleep(&tssrc, &tsret);
+}
+
diff --git a/executablecode/src/mytimelib.h b/executablecode/src/mytimelib.h
new file mode 100644
index 0000000000..ef4d1797c1
--- /dev/null
+++ b/executablecode/src/mytimelib.h
@@ -0,0 +1,13 @@
+#ifndef MYTIMELIB_H
+#define MYTIMELIB_H
+
+#include <time.h>
+
+// in usec
+void addTime(struct timespec *src1, struct timespec *src2, struct timespec *dest);
+int isBefore(struct timespec *src1, struct timespec *src2);
+void minTime(struct timespec *src1, struct timespec *src2, struct timespec *dest);
+void delayToTimeSpec(struct timespec *ts, long delay);
+extern void waitFor(long minDelay, long maxDelay);
+
+#endif
diff --git a/executablecode/src/random.c b/executablecode/src/random.c
index 9ac9c9dd29..c2be322463 100644
--- a/executablecode/src/random.c
+++ b/executablecode/src/random.c
@@ -2,14 +2,28 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
+#include <limits.h>
 
 #include "random.h"
-
+#include "debug.h"
+#include <math.h>
 
 int computeRandom(int min, int max) {
   return (rand() % (max - min)) + min;
 }
 
+long computeLongRandom(long min, long max) {
+
+  long rand0 = (((long)(rand()))*powl(2, ((((sizeof(long)-2))*8)-1)));
+  long rand1 = rand0 % (max - min);
+  //debugLong("min=", min);
+  //debugLong("max=", max);
+  //debugLong("rand0", rand0);
+  //debugLong("rand1", rand1);
+  debugLong("Random long", rand1 + min);
+  return rand1 + min;
+}
+
 void initRandom() {
   struct timespec ts;
 
diff --git a/executablecode/src/random.h b/executablecode/src/random.h
index f218733888..ecff7cb43c 100644
--- a/executablecode/src/random.h
+++ b/executablecode/src/random.h
@@ -3,5 +3,5 @@
 
 extern void initRandom();
 extern int computeRandom(int min, int max);
-
+extern long computeLongRandom(long min, long max);
 #endif
diff --git a/executablecode/src/request.c b/executablecode/src/request.c
index 9aebb05824..e207c42af9 100644
--- a/executablecode/src/request.c
+++ b/executablecode/src/request.c
@@ -3,31 +3,46 @@
 #include <unistd.h>
 
 #include "request.h"
+#include "mytimelib.h"
 #include "myerrors.h"
+#include "random.h"
+#include "debug.h"
 
 
-request *getNewRequest(int type, int hasDelay, long minDelay, long maxDelay, int nbOfParams, int **params) {
+request *getNewRequest(int ID, int type, int hasDelay, long minDelay, long maxDelay, int nbOfParams, int **params) {
   request *req = (request *)(malloc(sizeof(struct request)));
   
   if (req == NULL) {
     criticalError("Allocation of request failed");
   }
 
-  makeNewRequest(req, type, hasDelay, minDelay, maxDelay, nbOfParams, params);  
+  makeNewRequest(req,  ID, type, hasDelay, minDelay, maxDelay, nbOfParams, params);  
   return req;
 }
 
-void makeNewRequest(request *req, int type, int hasDelay, long minDelay, long maxDelay, int nbOfParams, int **params) {
+
+// Delays are in microseconds
+void makeNewRequest(request *req, int ID, int type, int hasDelay, long minDelay, long maxDelay, int nbOfParams, int **params) {
+  long delay;
+
   req->next = NULL;
   req->listOfRequests = NULL;
   req->type = type;
+  req->ID = ID;
   req->hasDelay = hasDelay;
-  req->minDelay = minDelay;
-  req->maxDelay = maxDelay;
+
+  if (req->hasDelay > 0) {
+    delay = computeLongRandom(minDelay, maxDelay);
+    delayToTimeSpec(&(req->delay), delay);
+  }
+
   req->selected = 0;
   req->nbOfParams = nbOfParams;
   req->params = params;
 
+  req->alreadyPending = 0;
+  req->delayElapsed = 0;
+
 }
 
 
@@ -146,6 +161,7 @@ void addRequestToList(setOfRequests *list, request* req) {
 
   if (list->head == NULL) {
     list->head = req;
+    req->nextRequestInList = NULL;
     return;
   }
 
@@ -155,4 +171,5 @@ void addRequestToList(setOfRequests *list, request* req) {
   }
 
   tmpreq->nextRequestInList = req;
+  req->nextRequestInList = NULL;
 }
diff --git a/executablecode/src/request.h b/executablecode/src/request.h
index 8830b8873e..bbb6888f2f 100644
--- a/executablecode/src/request.h
+++ b/executablecode/src/request.h
@@ -25,6 +25,10 @@ struct setOfRequests {
   timespec completionTime;
   pthread_cond_t *wakeupCondition;
   pthread_mutex_t *mutex;
+
+  int hasATimeRequest; // Means that at least on request of the list hasn't completed yet its time delay
+  timespec minTimeToWait;
+  struct request *selectedRequest;
 };
 
 typedef struct setOfRequests setOfRequests;
@@ -36,19 +40,24 @@ struct request {
   struct syncchannel *syncChannel;
   struct asyncchannel *asyncChannel;
   int type;
-  int hasDelay;
-  long minDelay;
-  long maxDelay;
-  int executable;
-  int selected;
+  int ID;
+  int hasDelay;;
+  timespec delay;
   int nbOfParams;
   int **params;
+
+  // Filled by the request manager
+  int executable;
+  int selected;
+  int alreadyPending; // Whether it has been taken into account for execution or not
+  int delayElapsed;
+  timespec myStartTime; // Time at which the delay has expired
 };
 
 typedef struct request request;
 
-request *getNewRequest(int type, int hasDelay, long minDelay, long maxDelay, int nbOfParams, int **params);
-void makeNewRequest(request *req, int type, int hasDelay, long minDelay, long maxDelay, int nbOfParams, int **params);
+void makeNewRequest(request *req, int ID, int type, int hasDelay, long minDelay, long maxDelay, int nbOfParams, int **params);
+request *getNewRequest(int ID, int type, int hasDelay, long minDelay, long maxDelay, int nbOfParams, int **params);
 void destroyRequest(request *req);
 extern int isRequestSelected(request *req);
 
diff --git a/executablecode/src/request_manager.c b/executablecode/src/request_manager.c
index 8d25822c4a..3582e5ddab 100644
--- a/executablecode/src/request_manager.c
+++ b/executablecode/src/request_manager.c
@@ -6,6 +6,8 @@
 #include "request.h"
 #include "myerrors.h"
 #include "debug.h"
+#include "mytimelib.h"
+#include "random.h"
 
 
 
@@ -40,6 +42,7 @@ void executeSendSyncTransaction(request *req) {
 
   // Select the selected request, and notify the information
   selectedReq->selected = 1;
+  selectedReq->listOfRequests->selectedRequest = selectedReq;
 
   // Handle parameters
   copyParameters(req, selectedReq);
@@ -76,6 +79,7 @@ void executeReceiveSyncTransaction(request *req) {
 
   // Select the request, and notify the information in the channel
   selectedReq->selected = 1;
+  selectedReq->listOfRequests->selectedRequest = selectedReq;
 
   // Handle parameters
   copyParameters(selectedReq, req);
@@ -85,84 +89,75 @@ void executeReceiveSyncTransaction(request *req) {
 }
 
 
-void executeSendSyncRequest(request *req, syncchannel *channel) {
-  /*debugMsg("Locking mutex");
-
-  if(channel == NULL) {
-    debugMsg("NULL channel");
-    exit(-1);
-  }
-
-  if(channel->mutex == NULL) {
-    debugMsg("NULL mutex");
-    exit(-1);
-  }
-
-  pthread_mutex_lock(channel->mutex);
-
-  debugMsg("Execute");
-  executeSendSyncTransaction(req, channel);
-
-  while (isRequestSelected(req) == 0) {
-    debugMsg("Stuck waiting for a receive request");
-    pthread_cond_wait(channel->sendCondition, channel->mutex);
-    debugMsg("Woke up from waiting for a receive request");
-  }
-
-  pthread_mutex_unlock(channel->mutex);
-  debugMsg("Mutex unlocked");*/
-
-}
-
-void executeReceiveSyncRequest(request *req, syncchannel *channel) {
-  /*debugMsg("Locking mutex");
-
-  pthread_mutex_lock(channel->mutex);
-
-  debugMsg("Execute");
-  executeReceiveSyncTransaction(req, channel);
-
-  while (isRequestSelected(req) == 0) {
-    debugMsg("Stuck waiting for a send request");
-    pthread_cond_wait(req->listOfRequests->wakeupCondition, channel->mutex);
-    debugMsg("Woke up from waiting for a send request");
-  }
-
-  pthread_mutex_unlock(channel->mutex);
-  debugMsg("Mutex unlocked");*/
-}
-
-
 int executable(setOfRequests *list, int nb) {
   int cpt = 0;
   int index = 0;
   request *req = list->head;
+  timespec ts;
+  int tsDone = 0;
 
   debugMsg("Starting loop");
 
+  list->hasATimeRequest = 0;
+
+  while(req != NULL) {
+    if (!(req->delayElapsed)) {
+      if (req->hasDelay) {
+	// Is the delay elapsed???
+	if (tsDone == 0) {
+	  clock_gettime(CLOCK_REALTIME, &ts);
+	  tsDone = 1;
+	}
+
+	if (isBefore(&(req->myStartTime), &ts)) {
+	  // 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;
+	  } else {
+	    minTime(&(req->myStartTime), &(list->minTimeToWait),&(list->minTimeToWait));
+	  }
+	}  else {
+	  // Delay elapsed
+	  debugMsg("---------t--------> delay elapsed");
+	  req->delayElapsed = 1;
+	}
+      } else {
+	req->delayElapsed = 1;
+      }
+    }
+    req = req->nextRequestInList;
+  }
+  
+  req = list->head;
   while((req != NULL) && (cpt < nb)) {
     req->executable = 0;
-    if (req->type == SEND_SYNC_REQUEST) {
-      debugMsg("Send sync");
-      if (req->syncChannel->inWaitQueue != NULL) {
-	req->executable = 1;
-	cpt ++;
-      } 
-      index ++;
-    }
+    if (req->delayElapsed) {
+      if (req->type == SEND_SYNC_REQUEST) {
+	debugMsg("Send sync");
+
+	if (req->syncChannel->inWaitQueue != NULL) {
+	  req->executable = 1;
+	  cpt ++;
+	} 
+	index ++;
+      }
 
-    if (req->type == RECEIVE_SYNC_REQUEST) {
-      debugMsg("receive sync");
-      if (req->syncChannel->outWaitQueue != NULL) {
+      if (req->type == RECEIVE_SYNC_REQUEST) {
+	debugMsg("receive sync");
+	if (req->syncChannel->outWaitQueue != NULL) {
+	  req->executable = 1;
+	  cpt ++;
+	}
+	index ++;
+      }
+
+      if (req->type == IMMEDIATE) {
 	req->executable = 1;
 	cpt ++;
       }
-      index ++;
-    }
-
-    if (req->type == IMMEDIATE) {
-      req->executable = 1;
-      cpt ++;
     }
 
     req = req->nextRequestInList;
@@ -175,11 +170,15 @@ int executable(setOfRequests *list, int nb) {
 void private__makeRequestPending(setOfRequests *list) {
   request *req = list->head;
   while(req != NULL) {
-    if (req->type == SEND_SYNC_REQUEST) {
-      req->syncChannel->outWaitQueue = addToRequestQueue(req->syncChannel->outWaitQueue, req);
-    }
-    if (req->type ==  RECEIVE_SYNC_REQUEST) {
-      req->syncChannel->inWaitQueue = addToRequestQueue(req->syncChannel->inWaitQueue, req);
+    if ((req->delayElapsed) && (!(req->alreadyPending))) {
+      if (req->type == SEND_SYNC_REQUEST) {
+	req->syncChannel->outWaitQueue = addToRequestQueue(req->syncChannel->outWaitQueue, req);
+	req->alreadyPending = 1;
+      }
+      if (req->type ==  RECEIVE_SYNC_REQUEST) {
+	req->alreadyPending = 1;
+	req->syncChannel->inWaitQueue = addToRequestQueue(req->syncChannel->inWaitQueue, req);
+      }
     }
 
     req = req->nextRequestInList;
@@ -206,7 +205,7 @@ request *private__executeRequests0(setOfRequests *list, int nb) {
   request *req;
   
   // Compute which requests can be executed
-  debugMsg("counting requests");
+  debugMsg("Counting requests");
   howMany = executable(list, nb);
 
   debugInt("Counting requests=", howMany);
@@ -242,6 +241,8 @@ request *private__executeRequests0(setOfRequests *list, int nb) {
 
   debugInt("Getting request at index", realIndex);
   selectedReq = getRequestAtIndex(list, realIndex);
+  selectedReq->selected = 1;
+  selectedReq->listOfRequests->selectedRequest = selectedReq;
 
   debugInt("Selected request of type", selectedReq->type);
 
@@ -254,18 +255,11 @@ request *private__executeRequests0(setOfRequests *list, int nb) {
 
 request *private__executeRequests(setOfRequests *list) {
   // Is a request already selected?
-  request *req;
-
-  req = list->head;
 
-  while(req != NULL) {
-    if (req->selected == 1) {
-      return req;
-    }
-    req = req->nextRequestInList;
+  if (list->selectedRequest != NULL) {
+    return list->selectedRequest;
   }
 
-
   debugMsg("No request selected -> looking for one!");
 
   return private__executeRequests0(list, nbOfRequests(list));
@@ -282,28 +276,57 @@ request *executeOneRequest(setOfRequests *list, request *req) {
 }
 
 
+void setLocalStartTime(setOfRequests *list) {
+  request *req = list->head;
+
+  while(req != NULL) {
+    if (req->hasDelay) {
+      req->delayElapsed = 0;
+      addTime(&(list->startTime), &(req->delay), &(req->myStartTime));
+      debugMsg(" -----t------>: Request with delay");
+    } else {
+      req->delayElapsed = 1;
+      req->myStartTime.tv_nsec = list->startTime.tv_nsec;
+      req->myStartTime.tv_sec = list->startTime.tv_sec;
+    }
+    req = req->nextRequestInList;
+  }
+}
+
+
 // Return the executed request
 request *executeListOfRequests(setOfRequests *list) {
   request *req;
 
   clock_gettime(CLOCK_REALTIME, &list->startTime);
+  list->selectedRequest = NULL;
+  setLocalStartTime(list);
   
   // Try to find a request that could be executed
+  debugMsg("Locking mutex");
   pthread_mutex_lock(list->mutex);
+  debugMsg("Mutex locked");
 
   debugMsg("Going to execute request");
 
   while((req = private__executeRequests(list)) == NULL) {
     debugMsg("Waiting for request!");
-    pthread_cond_wait(list->wakeupCondition, list->mutex);
-    debugMsg("Waking up for requests!");
+    if (list->hasATimeRequest == 1) {
+      debugMsg("Waiting for a request and at most for a given time");
+      pthread_cond_timedwait(list->wakeupCondition, list->mutex, &(list->minTimeToWait));
+    } else {
+      debugMsg("Releasing mutex");
+      pthread_cond_wait(list->wakeupCondition, list->mutex);
+    }
+    debugMsg("Waking up for requests! -> getting mutex");
   }
 
   debugMsg("Request selected!");
 
   clock_gettime(CLOCK_REALTIME, &list->completionTime);
 
-  pthread_mutex_unlock(list->mutex);  
+  pthread_mutex_unlock(list->mutex); 
+  debugMsg("Mutex unlocked");
   return req;
 }
 
diff --git a/executablecode/src/request_manager.h b/executablecode/src/request_manager.h
index 570b83c004..b5149a4d72 100644
--- a/executablecode/src/request_manager.h
+++ b/executablecode/src/request_manager.h
@@ -6,9 +6,6 @@
 #include "syncchannel.h"
 
 
-void executeSendSyncRequest(request *req, syncchannel *channel);
-void executeReceiveSyncRequest(request *req, syncchannel *channel);
-
 request *executeOneRequest(setOfRequests *list, request *req);
 request *executeListOfRequests(setOfRequests *list);
 #endif
diff --git a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java
index 6ff9abdfba..273ee45a9a 100755
--- a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java
+++ b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java
@@ -55,6 +55,11 @@ import avatartranslator.*;
 
 public class AVATAR2CPOSIX {
 
+	private final static int USEC = 0;
+	private final static int MSEC = 1;
+	private final static int SEC = 2;
+	
+	
 	private final static String GENERATED_PATH = "generated_src" + File.separator;
 	private final static String UNKNOWN = "UNKNOWN";
 	private final static String CR = "\n";
@@ -67,11 +72,17 @@ public class AVATAR2CPOSIX {
 	private Vector<TaskFile> taskFiles;
 	private String makefile_src;
 	
+	private int timeUnit;
+	
 
 	public AVATAR2CPOSIX(AvatarSpecification _avspec) {
 		avspec = _avspec;
 	}
 	
+	public void setTimeUnit(int _timeUnit) {
+		timeUnit = _timeUnit;
+	}
+	
 	public static String getGeneratedPath() {
 		return GENERATED_PATH;
 	}
@@ -315,6 +326,10 @@ public class AVATAR2CPOSIX {
 				ret += "}" + CR;
 			}
 			
+			if (at.hasDelay()) {
+				ret+= "waitFor(" + reworkDelay(at.getMinDelay()) + ", " + reworkDelay(at.getMaxDelay()) + ");" + CR;
+			}
+			
 			for(i=0; i<at.getNbOfAction(); i++) {
 				ret += at.getAction(i) + ";" + CR;
 			}
@@ -457,10 +472,10 @@ public class AVATAR2CPOSIX {
 					ret += "__params" + _index + "[" + i + "] = &" +  _aaos.getValue(i) + ";" + CR;
 				}
 				if (ar.isAsynchronous()) {
-					ret += "makeNewRequest(&__req" + _index + ", SEND_ASYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
+					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", SEND_ASYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
 					ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR;
 				} else {
-					ret += "makeNewRequest(&__req" + _index + ", SEND_SYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
+					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_SYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
 					ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR;
 				}
 				
@@ -470,10 +485,10 @@ public class AVATAR2CPOSIX {
 					ret += "__params" + _index + "[" + i + "] = &" +  _aaos.getValue(i) + ";" + CR;
 				}
 				if (ar.isAsynchronous()) {
-					ret += "makeNewRequest(&__req" + _index + ", RECEIVE_ASYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
+					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_ASYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
 					ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR;
 				} else {
-					ret += "makeNewRequest(&__req" + _index + ", RECEIVE_SYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
+					ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_SYNC_REQUEST, 0, 0, 0, " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR;
 					ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR;
 				}
 			}
@@ -489,7 +504,11 @@ public class AVATAR2CPOSIX {
 			ret += "if (" + g + ") {" + CR;
 		}
 		
-		ret += "makeNewRequest(&__req" + _index + ", IMMEDIATE, 0, 0, 0, 0, __params" + _index + ");" + CR;
+		if (_at.hasDelay()) {
+			ret += "makeNewRequest(&__req" + _index + ", " + _at.getID() + ", IMMEDIATE, 1, " + reworkDelay(_at.getMinDelay()) + ", " + reworkDelay(_at.getMaxDelay()) + ", 0, __params" + _index + ");" + CR;
+		} else {
+			ret += "makeNewRequest(&__req" + _index + ", " + _at.getID() + ", IMMEDIATE, 0, 0, 0, 0, __params" + _index + ");" + CR;
+		}
 		ret += "addRequestToList(&__list, &__req" + _index + ");" + CR;
 		if (_at.isGuarded()) {
 			ret += "}" + CR;
@@ -577,6 +596,20 @@ public class AVATAR2CPOSIX {
 		g = Conversion.replaceOp(g, "not", "!");
 		return g;
 	}
+	
+	public String reworkDelay(String _delay) {
+		
+		switch(timeUnit) {
+		case USEC:
+			return _delay;
+		case MSEC:
+			return "(" + _delay + ")*1000";
+		case SEC:
+			return "(" + _delay + ")*1000000";
+		}
+		
+		return _delay;
+	}
 				
 	
 }
\ No newline at end of file
diff --git a/src/avatartranslator/toexecutable/TaskFile.java b/src/avatartranslator/toexecutable/TaskFile.java
index cb1c5f5def..36c602ac52 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 \"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 \"main.h\""; 
 	
 	private final static String CR = "\n";
 	
diff --git a/src/ui/window/JDialogAvatarExecutableCodeGeneration.java b/src/ui/window/JDialogAvatarExecutableCodeGeneration.java
index 0a954d6921..659fbe0e0e 100644
--- a/src/ui/window/JDialogAvatarExecutableCodeGeneration.java
+++ b/src/ui/window/JDialogAvatarExecutableCodeGeneration.java
@@ -63,6 +63,8 @@ import launcher.*;
 
 public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JDialog implements ActionListener, Runnable, MasterProcessInterface  {
     
+	private static String[] unitTab = {"usec", "msec", "sec"}; 
+	
     protected MainGUI mgui;
     
     private String textSysC1 = "Base directory of code generation code:";
@@ -101,7 +103,9 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JDialog i
     protected JTabbedPane jp1;
     protected JScrollPane jsp;
     protected JCheckBox removeCFiles, removeXFiles, debugmode, optimizemode;
-	protected JComboBox versionCodeGenerator;
+	protected JComboBox versionCodeGenerator, units;
+	
+	private static int selectedUnit = 2;
 	
     
     private Thread t;
@@ -209,6 +213,13 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JDialog i
 		optimizemode.setSelected(optimizeModeSelected);
         jp01.add(optimizemode, c01);
 		
+		jp01.add(new JLabel("1 time unit ="), c01);
+		
+		units = new JComboBox(unitTab);
+		units.setSelectedIndex(selectedUnit);
+		units.addActionListener(this);
+		jp01.add(units, c01);
+		
 		jp01.add(new JLabel("Code generator used:"), c01);
 		
 		versionCodeGenerator = new JComboBox(codes);
@@ -325,6 +336,8 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JDialog i
             closeDialog();
         } else if (evt.getSource() == versionCodeGenerator) {
 			selectedItem = versionCodeGenerator.getSelectedIndex();
+		} else if (evt.getSource() == units) {
+			selectedUnit = units.getSelectedIndex();
 		}
     }
     
@@ -406,6 +419,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JDialog i
 					testGo();
 					
 					selectedItem = versionCodeGenerator.getSelectedIndex();
+					selectedUnit = units.getSelectedIndex();
 					//System.out.println("Selected item=" + selectedItem);
 					if (selectedItem == 0) {
 						AvatarSpecification avspec = mgui.gtm.getAvatarSpecification();
@@ -415,6 +429,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JDialog i
 							jta.append("Error: No AVATAR specification\n");
 						} else {
 							AVATAR2CPOSIX avatartocposix = new AVATAR2CPOSIX(avspec);
+							avatartocposix.setTimeUnit(selectedUnit);
 							avatartocposix.generateCPOSIX(debugmode.isSelected());
 							testGo();
 							jta.append("Generation of C-POSIX executable code: done\n");
-- 
GitLab