diff --git a/executablecode/Makefile.src b/executablecode/Makefile.src index 28b9acb23f0af46aef4caec4f72c265800a703d3..b2ad698f7971c10004410fbec520ed85cf2b0480 100755 --- a/executablecode/Makefile.src +++ b/executablecode/Makefile.src @@ -1 +1 @@ -SRCS = generated_src/main.c generated_src/ObserverProp1.c generated_src/RemotelyControlledMicrowave.c generated_src/RemoteControl.c generated_src/MicroWaveOven.c generated_src/Bell.c generated_src/ControlPanel.c generated_src/Controller.c generated_src/Magnetron.c generated_src/Door.c generated_src/WirelessInterface.c \ No newline at end of file +SRCS = generated_src/main.c generated_src/System.c generated_src/Receiver2.c generated_src/Receiver1.c generated_src/Sender.c \ No newline at end of file diff --git a/executablecode/src/request.c b/executablecode/src/request.c index c9d287f7be7cc03a48c901bb4b077087eeba8f30..0e495195edf8e68d195bb696fe386e59d95b89e7 100644 --- a/executablecode/src/request.c +++ b/executablecode/src/request.c @@ -192,17 +192,68 @@ void removeAllPendingRequestsFromPendingLists(request *req, int apartThisOne) { debugInt("Considering request of type", reqtmp->type); if (reqtmp->alreadyPending) { if (reqtmp->type == RECEIVE_SYNC_REQUEST) { - debugMsg("Removing request from inWaitQueue"); + debugMsg("Removing send sync request from inWaitQueue"); reqtmp->syncChannel->inWaitQueue = removeRequestFromList(reqtmp->syncChannel->inWaitQueue, reqtmp); debugMsg("done"); } if (reqtmp->type == SEND_SYNC_REQUEST) { - debugMsg("Removing request from outWaitQueue"); + debugMsg("Removing receive sync request from outWaitQueue"); reqtmp->syncChannel->outWaitQueue = removeRequestFromList(reqtmp->syncChannel->outWaitQueue, reqtmp); debugMsg("done"); } + + if (reqtmp->type == RECEIVE_BROADCAST_REQUEST) { + debugMsg("Removing broadcast receive request from inWaitQueue"); + reqtmp->syncChannel->inWaitQueue = removeRequestFromList(reqtmp->syncChannel->inWaitQueue, reqtmp); + debugMsg("done"); + } } reqtmp = reqtmp->nextRequestInList; } } + + +// Identical means belonging to the same ListOfRequest +// Returns the identical request if found, otherwise, null +request *hasIdenticalRequestInListOfSelectedRequests(request *req, request *list) { + + while(list != NULL) { + if (list->listOfRequests == req->listOfRequests) { + return list; + } + list = list->relatedRequest; + } + + return NULL; +} + +request* replaceInListOfSelectedRequests(request *oldRequest, request *newRequest, request *list) { + request *head = list; + + if (list == oldRequest) { + newRequest->relatedRequest = oldRequest->relatedRequest; + return newRequest; + } + + //list=list->relatedRequest; + while(list->relatedRequest != oldRequest) { + list = list->relatedRequest; + } + + list->relatedRequest = newRequest; + newRequest->relatedRequest = oldRequest->relatedRequest; + + return head; +} + + +int nbOfRelatedRequests(request *list) { + int cpt = 0; + while(list->relatedRequest != NULL) { + cpt ++; + list = list->relatedRequest; + } + + return cpt; +} diff --git a/executablecode/src/request.h b/executablecode/src/request.h index 9856f72678659c35a2c5753780683114ebf74f82..607941ed374bccbb37280e2e338ae363f3abc2cb 100644 --- a/executablecode/src/request.h +++ b/executablecode/src/request.h @@ -16,6 +16,8 @@ struct request; #define RECEIVE_ASYNC_REQUEST 6 #define DELAY 8 #define IMMEDIATE 10 +#define SEND_BROADCAST_REQUEST 12 +#define RECEIVE_BROADCAST_REQUEST 14 typedef struct timespec timespec; @@ -38,7 +40,7 @@ struct request { struct request *next; struct setOfRequests* listOfRequests; struct request* nextRequestInList; - struct request* relatedRequest; // For synchro for example + struct request* relatedRequest; // For synchro and broadcast struct syncchannel *syncChannel; struct asyncchannel *asyncChannel; int type; @@ -79,4 +81,8 @@ void clearListOfRequests(setOfRequests *list); void fillListOfRequests(setOfRequests *list, char *name, pthread_cond_t *wakeupCondition, pthread_mutex_t *mutex); void removeAllPendingRequestsFromPendingLists(request *req, int apartThisOne); +request *hasIdenticalRequestInListOfSelectedRequests(request *req, request *list); +request* replaceInListOfSelectedRequests(request *oldRequest, request *newRequest, request *list); +int nbOfRelatedRequests(request *list); + #endif diff --git a/executablecode/src/request_manager.c b/executablecode/src/request_manager.c index 1d309353654333390bcac4c7adca0d47dee47204..a9f52fa6a879a483cc309d00de4e10637441c378 100644 --- a/executablecode/src/request_manager.c +++ b/executablecode/src/request_manager.c @@ -93,9 +93,67 @@ void executeReceiveSyncTransaction(request *req) { } +void executeSendBroadcastTransaction(request *req) { + int cpt; + request *tmpreq; + + // At least one transaction available -> must select all of them + // but at most one per task + // Then, broadcast the new condition! + + request* currentReq = req->syncChannel->inWaitQueue; + request* currentLastReq = req; + debugMsg("Execute broadcast sync tr"); + + + while(currentReq != NULL) { + tmpreq = hasIdenticalRequestInListOfSelectedRequests(currentReq, req->relatedRequest); + if (tmpreq != NULL) { + // Must select one of the two + // If =1, replace, otherwise, just do nothing + cpt = random() % 2; + if (cpt == 1) { + debugMsg("Replacing broadcast request"); + req->relatedRequest = replaceInListOfSelectedRequests(tmpreq, currentReq, req->relatedRequest); + currentReq->listOfRequests->selectedRequest = currentReq; + copyParameters(req, currentReq); + currentReq->selected = 1; + currentLastReq = req; + while(currentLastReq->relatedRequest != NULL) { + currentLastReq = currentLastReq->relatedRequest; + } + } + } else { + currentLastReq->relatedRequest = currentReq; + currentReq->relatedRequest = NULL; + currentReq->selected = 1; + currentReq->listOfRequests->selectedRequest = currentReq; + copyParameters(req, currentReq); + currentLastReq = currentReq; + } + + currentReq = currentReq->next; + + debugInt("Nb of requests selected:", nbOfRelatedRequests(req)); + } + + + debugMsg("Signaling"); + currentReq = req->relatedRequest; + cpt = 0; + while(currentReq != NULL) { + cpt ++; + pthread_cond_signal(currentReq->listOfRequests->wakeupCondition); + currentReq = currentReq->relatedRequest; + } + + debugInt("NUMBER of broadcast Requests", cpt); +} + + int executable(setOfRequests *list, int nb) { int cpt = 0; - int index = 0; + //int index = 0; request *req = list->head; timespec ts; int tsDone = 0; @@ -152,7 +210,7 @@ int executable(setOfRequests *list, int nb) { } else { debugMsg("Send sync not executable"); } - index ++; + //index ++; } if (req->type == RECEIVE_SYNC_REQUEST) { @@ -161,9 +219,23 @@ int executable(setOfRequests *list, int nb) { req->executable = 1; cpt ++; } - index ++; + //index ++; + } + + if (req->type == SEND_BROADCAST_REQUEST) { + debugMsg("send broadcast"); + req->executable = 1; + cpt ++; } + if (req->type == RECEIVE_BROADCAST_REQUEST) { + debugMsg("receive broadcast"); + // A receive broadcast is never executable + req->executable = 0; + //index ++; + } + + if (req->type == IMMEDIATE) { debugMsg("immediate"); req->executable = 1; @@ -192,6 +264,19 @@ void private__makeRequestPending(setOfRequests *list) { req->alreadyPending = 1; req->syncChannel->inWaitQueue = addToRequestQueue(req->syncChannel->inWaitQueue, req); } + + if (req->type == RECEIVE_BROADCAST_REQUEST) { + debugMsg("Adding pending broadcast request in inWaitqueue"); + req->alreadyPending = 1; + req->syncChannel->inWaitQueue = addToRequestQueue(req->syncChannel->inWaitQueue, req); + } + + if (req->type == SEND_BROADCAST_REQUEST) { + debugMsg("Adding pending broadcast request in outWaitqueue"); + req->alreadyPending = 1; + req->syncChannel->outWaitQueue = addToRequestQueue(req->syncChannel->outWaitQueue, req); + } + } req = req->nextRequestInList; @@ -207,16 +292,30 @@ void private__makeRequest(request *req) { executeReceiveSyncTransaction(req); } + if (req->type == SEND_BROADCAST_REQUEST) { + executeSendBroadcastTransaction(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); + removeAllPendingRequestsFromPendingListsRelatedRequests(req); + /*if (req->relatedRequest != NULL) { + debugMsg("Removing related req"); + removeAllPendingRequestsFromPendingLists(req->relatedRequest, 0); + }*/ + +} + +void removeAllPendingRequestsFromPendingListsRelatedRequests(request *req) { if (req->relatedRequest != NULL) { debugMsg("Removing related req"); removeAllPendingRequestsFromPendingLists(req->relatedRequest, 0); + // Recursive call + removeAllPendingRequestsFromPendingListsRelatedRequests(req->relatedRequest); } - } @@ -241,7 +340,7 @@ request *private__executeRequests0(setOfRequests *list, int nb) { return NULL; } - debugInt("At least one pending request", howMany); + debugInt("At least one pending request is executable", howMany); // Select a request diff --git a/executablecode/src/request_manager.h b/executablecode/src/request_manager.h index b5149a4d72ea438df742c967fb2847132e07c967..e2ae0f800025b9394d6488c012b47f7396aaf609 100644 --- a/executablecode/src/request_manager.h +++ b/executablecode/src/request_manager.h @@ -8,4 +8,7 @@ request *executeOneRequest(setOfRequests *list, request *req); request *executeListOfRequests(setOfRequests *list); + +void removeAllPendingRequestsFromPendingListsRelatedRequests(request *req); + #endif diff --git a/executablecode/src/syncchannel.h b/executablecode/src/syncchannel.h index 93c6c1c0329afbfa99dd127bdb7e537171ce2aff..6f4f92de5531f14c36b7d520992eb3decb305cdd 100644 --- a/executablecode/src/syncchannel.h +++ b/executablecode/src/syncchannel.h @@ -17,7 +17,7 @@ struct syncchannel { typedef struct syncchannel syncchannel; - +void setBroadcast(syncchannel *syncch, bool b); syncchannel *getNewSyncchannel(char *inname, char *outname); //request *makeNewSendSync(int hasDelay, long delay, int nbOfParams, int *params[]); //request *makeNewReceiveSync(int hasDelay, long delay, int nbOfParams, int *params[]); diff --git a/executablecode/src/tracemanager.c b/executablecode/src/tracemanager.c index 894488b551d9d056d815d2a333c795498313f94e..b06dbaeb12ca3f73723e94b4a76d2318ae8d14d5 100644 --- a/executablecode/src/tracemanager.c +++ b/executablecode/src/tracemanager.c @@ -137,6 +137,14 @@ void traceRequest(char *myname, request *req) { case RECEIVE_SYNC_REQUEST: sprintf(s, "block=%s type=receive_synchro channel=%s\n", myname, req->syncChannel->inname); break; + case SEND_BROADCAST_REQUEST: + debug2Msg("Sync channel", req->syncChannel->outname); + sprintf(s, "block=%s type=send_broadcast channel=%s\n", myname, req->syncChannel->outname); + break; + case RECEIVE_BROADCAST_REQUEST: + debug2Msg("Sync channel", req->syncChannel->outname); + sprintf(s, "block=%s type=receive_broadcast channel=%s\n", myname, req->syncChannel->outname); + break; case IMMEDIATE: sprintf(s, "block=%s type=action\n", myname); break; diff --git a/src/avatartranslator/directsimulation/AvatarSimulationBlock.java b/src/avatartranslator/directsimulation/AvatarSimulationBlock.java index 7067af554a6ca5e1680b025a132ef7bfea3d575b..cdf186961cb221f939268209a3e90c53d91b11a0 100644 --- a/src/avatartranslator/directsimulation/AvatarSimulationBlock.java +++ b/src/avatartranslator/directsimulation/AvatarSimulationBlock.java @@ -370,7 +370,7 @@ public class AvatarSimulationBlock { // Must put the right parameters if (_aspt.isSynchronous) { // Synchronous call - if ((_aspt.isSending) && (_aspt.linkedTransaction != null )){ + if ((_aspt.isSending) && ((_aspt.linkedTransaction != null ) || (_aspt.linkedTransactions != null))){ // Synchronous Sending! // Must be in the receiving transaction the right parameters Vector<String> parameters = new Vector<String>(); @@ -395,7 +395,15 @@ public class AvatarSimulationBlock { } } //for(i=0; i<_aspt.linkedTransactions.size(); i++) { - _aspt.linkedTransaction.parameters = parameters; + if (_aspt.linkedTransaction != null) { + _aspt.linkedTransaction.parameters = parameters; + } + + if (_aspt.linkedTransactions != null) { + for(AvatarSimulationPendingTransaction aspt0: _aspt.linkedTransactions) { + aspt0.parameters = parameters; + } + } //} } else if ((!(_aspt.isSending)) && (_aspt.parameters != null)){ //TraceManager.addDev("Reading value " + aaos); diff --git a/src/avatartranslator/directsimulation/AvatarSimulationPendingTransaction.java b/src/avatartranslator/directsimulation/AvatarSimulationPendingTransaction.java index e596de1a044d814cddb5e39dc1ca107a87d43b45..be2297af7a1cbdd9ca0d7f9980d0edb804af081e 100644 --- a/src/avatartranslator/directsimulation/AvatarSimulationPendingTransaction.java +++ b/src/avatartranslator/directsimulation/AvatarSimulationPendingTransaction.java @@ -47,11 +47,13 @@ knowledge of the CeCILL license and that you accept its terms. package avatartranslator.directsimulation; +import java.awt.*; import java.util.*; import avatartranslator.*; import myutil.*; + public class AvatarSimulationPendingTransaction { public AvatarSimulationBlock asb; @@ -183,6 +185,40 @@ public class AvatarSimulationPendingTransaction { res += "[SYNCHRO]" + elementToExecute.getNiceName() + "/ID=" + elementToExecute.getID(); res += " | " + linkedTransaction.toString(); } + + if (linkedTransactions != null) { + res += " --to--> ["; + int cpt = 0; + for(AvatarSimulationPendingTransaction aspt: linkedTransactions) { + if (cpt == 0) { + cpt ++; + } else { + res += " "; + } + res += aspt.elementToExecute.getID(); + } + res += "]"; + } + return res; } + + public Point hasDuplicatedBlockTransaction() { + Vector<AvatarSimulationBlock> blocks = new Vector<AvatarSimulationBlock>(); + + if (linkedTransactions == null) { + return null; + } + + for(AvatarSimulationPendingTransaction aspt: linkedTransactions) { + if (blocks.contains(aspt.asb)) { + return new Point(blocks.indexOf(aspt.asb), blocks.size()); + } + blocks.add(aspt.asb); + + } + return null; + } + + } \ No newline at end of file diff --git a/src/avatartranslator/directsimulation/AvatarSpecificationSimulation.java b/src/avatartranslator/directsimulation/AvatarSpecificationSimulation.java index 399cf0167a111f3bf90a78ec3da17423817a5b12..c5717f4af52cad264d40d8604e631ae647118fe8 100644 --- a/src/avatartranslator/directsimulation/AvatarSpecificationSimulation.java +++ b/src/avatartranslator/directsimulation/AvatarSpecificationSimulation.java @@ -47,6 +47,7 @@ knowledge of the CeCILL license and that you accept its terms. package avatartranslator.directsimulation; +import java.awt.*; import java.util.*; import avatartranslator.*; @@ -492,7 +493,7 @@ public class AvatarSpecificationSimulation { // Transactions are only put with one another // Synchronous transactions: the sending one has a link to the receiving one // Work on broadcast transactions - // ll = workOnBroadcastTransactions(ll); + ll = workOnBroadcastTransactions(ll); // Select possible logical transactions @@ -1038,34 +1039,33 @@ public class AvatarSpecificationSimulation { } - private Vector<AvatarSimulationPendingTransaction> workOnBroadcastTransactions(Vector<AvatarSimulationPendingTransaction> transactions) { + // Must split transactions when a broadcast transactions contains more than one transaction per block + private Vector<AvatarSimulationPendingTransaction> workOnBroadcastTransactions(Vector<AvatarSimulationPendingTransaction> _transactions) { Vector<AvatarSimulationPendingTransaction> ll = new Vector<AvatarSimulationPendingTransaction>(); - Vector<AvatarSimulationPendingTransaction> met = new Vector<AvatarSimulationPendingTransaction>(); - boolean isMet; - - for (AvatarSimulationPendingTransaction aspt: transactions) { - if (!(aspt.isBroadcast)) { - ll.add(aspt); - } else { - isMet = false; - for (AvatarSimulationPendingTransaction maspt: met) { - if (aspt.elementToExecute == aspt.elementToExecute) { - isMet = true; - break; - } - } - if (!isMet) { - workOnABroadcastTransaction(transactions, ll, aspt); - met.add(aspt); - } - } - } - - - // Must remove redondant transactions - - return ll; + AvatarSimulationPendingTransaction asptfound, newaspt; + Point p; + + while(true) { + asptfound = null; + p = null; + for(AvatarSimulationPendingTransaction aspt: _transactions) { + if ((aspt.isBroadcast) && (aspt.linkedTransactions != null)) { + if ((p = aspt.hasDuplicatedBlockTransaction()) != null) { + TraceManager.addDev("FOUND DUPLICATED BLOCK"); + asptfound = aspt; + break; + } + } + } + if (asptfound == null) { + return _transactions; + } + newaspt = asptfound.fullCloneMe(); + newaspt.linkedTransactions.removeElementAt(p.x); + _transactions.add(newaspt); + asptfound.linkedTransactions.removeElementAt(p.y); + } } private void workOnABroadcastTransaction(Vector<AvatarSimulationPendingTransaction> _oldTransactions, Vector<AvatarSimulationPendingTransaction> _newTransactions, AvatarSimulationPendingTransaction _aspt) { diff --git a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java index 415011f65ef364b7cdd2295606ae1c16870f25d6..76cc998becefa2de0a3df7c13a86cd6a9581d8aa 100755 --- a/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java +++ b/src/avatartranslator/toexecutable/AVATAR2CPOSIX.java @@ -564,8 +564,13 @@ public class AVATAR2CPOSIX { 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, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + if (ar.isBroadcast()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_BROADCAST_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_SYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } } // Receiving @@ -577,8 +582,13 @@ public class AVATAR2CPOSIX { ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_ASYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR; } else { + if (ar.isBroadcast()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_BROADCAST_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { 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/ui/avatarinteractivesimulation/AvatarSpecificationSimulationSDPanel.java b/src/ui/avatarinteractivesimulation/AvatarSpecificationSimulationSDPanel.java index ca10103bc31636e799bc1e1ab1e29ee32b67a20c..1f59cbc28f472b2e570279a5919775f08913aef4 100644 --- a/src/ui/avatarinteractivesimulation/AvatarSpecificationSimulationSDPanel.java +++ b/src/ui/avatarinteractivesimulation/AvatarSpecificationSimulationSDPanel.java @@ -553,7 +553,7 @@ public class AvatarSpecificationSimulationSDPanel extends JPanel implements Mous messageName += ast.actions.get(0); } messageName += ")"; - + currentY += 10; g.setColor(ColorManager.AVATAR_SEND_SIGNAL); g.drawLine(currentX+spaceBetweenLifeLines-spaceBroadcast, currentY-1, currentX, currentY-1);