address addrPrec(address ad, addressSet circuit){ int i=addrToRank(ad); if (i==(-1)) { ERROR_AT_LINE_WITHOUT_ERRNUM(EXIT_FAILURE,__FILE__,__LINE__,"addr not found"); } do { i=(i+NP-1) % NP; } while (!addrIsMember(rankToAddr(i), circuit)); return rankToAddr(i); }
//Use to send all the messages Msg, even the TRAIN ones, but in fact, TRAIN messages will never be created for the sending, but use only on reception... Thus, to send TRAIN messages, sendTrain will be used. //use globalAddrArray defined in management_addr.h int sendOther(address addr, bool isPred, MType type, address sender){ int length; int iovcnt = 1; struct iovec iov[1]; int rank = -1; trComm * aComm; int result; Msg * msg; if (type == TRAIN) { error_at_line(EXIT_FAILURE, errno, __FILE__, __LINE__, "Wrong MType given to sendOther"); return (-1); } else { msg = malloc(sizeof(newMsg(type, sender))); *msg = newMsg(type, sender); length = msg->len; rank = addrToRank(addr); if (rank != -1) { aComm = getTComm(rank, isPred, globalAddrArray); if (aComm == NULL ) { free(msg); return (-1); } //printf("Send message = %s on comm %p\n", msgTypeToStr(type), aComm); iov[0].iov_base = msg; iov[0].iov_len = length; result = commWritev(aComm, iov, iovcnt); if (result != length) fprintf(stderr, "result!=length\n"); free(msg); return (result); } else { //should return an error if the addr is out of rank free(msg); error_at_line(EXIT_FAILURE, errno, __FILE__, __LINE__, "Sending failure in sendOther (addr = %d)", addr); return (-1); //same error as commWritev !! } } }
void participate(bool b) { static trComm *commForAccept = NULL; pthread_t thread; if (b) { commForAccept = commNewForAccept( globalAddrArray[addrToRank(myAddress)].chan); if (commForAccept == NULL ) ERROR_AT_LINE(EXIT_FAILURE, errno, __FILE__, __LINE__, "commNewForAccept"); int rc = pthread_create(&thread, NULL, &acceptMgt, (void *) commForAccept); if (rc < 0) ERROR_AT_LINE(EXIT_FAILURE, rc, __FILE__, __LINE__, "pthread_create"); rc = pthread_detach(thread); if (rc < 0) ERROR_AT_LINE(EXIT_FAILURE, rc, __FILE__, __LINE__, "pthread_detach"); } else { freeComm(commForAccept); } }
//send a train -> use sendOther to send the rest int sendTrain(address addr, bool isPred, ltsStruct lts){ int iovcnt = 3; struct iovec iov[iovcnt]; int rank = -1; trComm * aComm; int result; rank = addrToRank(addr); if (rank != -1) { aComm = getTComm(rank, isPred, globalAddrArray); if (aComm == NULL ) { return (-1); } //printf("The train %d/%d is sent to %d on comm %p\n",lts.stamp.id,lts.stamp.lc,addr, aComm); lts.lng = sizeof(lts.lng) + sizeof(lts.type) + sizeof(lts.stamp) + sizeof(lts.circuit); //to begin, let's enter the length of the message iov[0].iov_base = &(lts); iov[0].iov_len = lts.lng; //after loading the wagons //look after to be sure there are wagons to send... if (lts.w.len != 0) { //check if there are wagons lts.lng += lts.w.len; iov[1].iov_base = lts.w.w_w.p_wagon; iov[1].iov_len = lts.w.len; } else { iov[1].iov_base = NULL; iov[1].iov_len = 0; } //finally loading the wagon which is waiting to be sent //look after to be sure that p_wtosend exists or not... if (lts.p_wtosend == NULL ) { //check if p_wtosend is NULL iov[2].iov_base = NULL; iov[2].iov_len = 0; } else { if (firstMsg(lts.p_wtosend->p_wagon) == NULL ) { //check if p_wtosend is not just a header printf("wagonToSend is just a header \n"); iov[2].iov_base = NULL; iov[2].iov_len = 0; } else { lts.lng += lts.p_wtosend->p_wagon->header.len; iov[2].iov_base = lts.p_wtosend->p_wagon; iov[2].iov_len = lts.p_wtosend->p_wagon->header.len; } } //sending the whole train with writev //returning the number of bytes sent result = commWritev(aComm, iov, iovcnt); if (result != lts.lng) fprintf(stderr, "result!=lts.lng (bis) with result=%i and length=%i (errno = %i / %s)\n", result, lts.lng, errno, strerror(errno)); return (result); } else { //should return an error if the addr is out of rank error_at_line(EXIT_FAILURE, errno, __FILE__, __LINE__, "Sending failure in sendTrain (addr = %d)", addr); return (-1); //same error as commWritev !! } }
char *addrToPort(address ad){ return globalAddrArray[addrToRank(ad)].chan; }
char *addrToHostname(address ad){ return globalAddrArray[addrToRank(ad)].ip; }
char *addrToStr(char *s, address ad){ sprintf(s, "#%02d", addrToRank(ad)); return s; }
int main() { addressSet arrivedSet; addressSet goneSet; compare("addrIsNull", addrIsNull(nullAddress), true); compare("addrIsNull", addrIsNull(myAddress), false); compare("addrCmp", addrCmp(nullAddress,myAddress), true); compare("addrCmp", addrCmp(myAddress,nullAddress), false); compare("addrIsEqual", addrIsEqual(nullAddress,nullAddress), true); compare("addrIsEqual", addrIsEqual(myAddress,nullAddress), false); compare("addrIsMine", addrIsMine(myAddress), true); compare("addrIsMine", addrIsMine(nullAddress), false); printf("Testing %s...", "addr_2_str"); addrToStr(s,myAddress); if (strcmp(s, "#00") != 0){ printf("... KO (s is \"%s\" instead of \"%s\")\n", s, "#00"); exit(EXIT_FAILURE); } printf("...OK\n"); compare("addrToRank", addrToRank(myAddress), 0); compare("addrToRank", addrToRank(0x8000), 15); compare("addrToRank", addrToRank(nullAddress), -1); compare("rankToAddr", rankToAddr(0), myAddress); compare("rankToAddr", rankToAddr(15), 0x8000); compare("rankToAddr", rankToAddr(16), nullAddress); compare("addrIsMember", addrIsMember(myAddress, 0xFFFF), true); compare("addrIsMember", addrIsMember(myAddress, 0xFFFE), false); arrivedSet = 0xFFFE; addrAppendArrived(&arrivedSet, myAddress); compare("addrAppendArrived", arrivedSet, 0xFFFF); arrivedSet = 0x0000; addrAppendArrived(&arrivedSet, myAddress); compare("addrAppendArrived", arrivedSet, 0x0001); arrivedSet = 0x0000; goneSet = 0xFFFE; addrAppendGone(&arrivedSet, &goneSet, myAddress); printf("Testing %s...", "addr_appendGone"); if ((arrivedSet != 0x0000) || (goneSet != 0xFFFF)){ printf("... KO (arrivedSet is \"%d\" instead of \"%d\" OR goneSet is \"%d\" instead of \"%d\")\n", arrivedSet, 0x0000, goneSet, 0xFFFF); exit(EXIT_FAILURE); } printf("...OK\n"); arrivedSet = 0xFFFF; goneSet = 0x0000; addrAppendGone(&arrivedSet, &goneSet, myAddress); printf("Testing %s...", "addr_appendGone"); if ((arrivedSet != 0xFFFE) || (goneSet != 0x0000)){ printf("... KO (arrivedSet is \"%d\" instead of \"%d\" OR goneSet is \"%d\" instead of \"%d\")\n", arrivedSet, 0xFFFF, goneSet, 0x0000); exit(EXIT_FAILURE); } printf("...OK\n"); compare("addrUpdateCircuit", addrUpdateCircuit(0xFFFF, myAddress, 0xFF00, 0x00FF), 0xFF00); compare("addrPrec", addrPrec(0x8000, 0x8000|0x0001), 0x0001); compare("addrPrec", addrPrec(0x0001, 0x8000|0x0001), 0x8000); return EXIT_SUCCESS; }