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