Esempio n. 1
0
//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 !!
  }
}
Esempio n. 2
0
void trainHandling(womim *p_womim) {
    int id = p_womim->msg.body.train.stamp.id;
    int round = p_womim->msg.body.train.stamp.round;
    wagon *p_wag;

    counters.recent_trains_received++;
    counters.recent_trains_bytes_received += p_womim->msg.len;
    //printf("TRAIN id=%d\n", id);
    if (round == lts[id].stamp.round) {
        round = (round + 1) % nbRounds;
    }
    if (requiredOrder != CAUSAL_ORDER) {
        // Thus (requiredOrder == TOTAL_ORDER) || (requiredOrder == UNIFORM_TOTAL_ORDER))
        bqueueExtend(wagonsToDeliver, unstableWagons[id][(round + 1) % nbRounds]);
        cleanList(unstableWagons[id][(round + 1) % nbRounds]);
    }
    if (id == 0) {
        lts[0].circuit = addrUpdateCircuit(p_womim->msg.body.train.circuit,
                                           myAddress, cameProc, goneProc);
        cameProc = 0;
        signalDepartures(goneProc, lts[0].circuit, false);
        goneProc = 0;
    } else {
        lts[id].circuit = lts[0].circuit;
    }

    releaseWiw(&(lts[id].w.w_w));
    lts[id].w.len = 0;
    freeWiw(lts[id].p_wtosend);
    lts[id].p_wtosend = NULL;

    for (p_wag = firstWagon(&(p_womim->msg)); p_wag != NULL ;
            p_wag = nextWagon(p_womim, p_wag)) {
        if (addrIsMember(p_wag->header.sender, lts[id].circuit)
                && !(addrIsMember(p_wag->header.sender, goneProc))
                && !(addrIsMine(p_wag->header.sender))) {
            // We add a wiw (corresponding to this p_wag) to unstableWagons[id][round]
            // (in case of TOTAL_ORDER or UNIFORM_TOTAL_ORDER) or directly to
            // wagonsToDeliver (in case of CAUSAL_ORDER)
            wiw *wi = malloc(sizeof(wiw));
            assert(wi != NULL);
            wi->p_wagon = p_wag;
            wi->p_womim = p_womim;
            MUTEX_LOCK(p_womim->pfx.mutex);
            p_womim->pfx.counter++;
            MUTEX_UNLOCK(p_womim->pfx.mutex);
            if (requiredOrder != CAUSAL_ORDER) {
                // Thus (requiredOrder == TOTAL_ORDER) || (requiredOrder == UNIFORM_TOTAL_ORDER))
                listAppend(unstableWagons[id][round], wi);
            } else {
                bqueueEnqueue(wagonsToDeliver, wi);
            }

            // Shall this wagon be sent to our successor
            if (!addrIsEqual(succ,p_wag->header.sender)) {
                // Yes, it must sent
                if (lts[id].w.w_w.p_wagon == NULL ) {
                    // lts must be updated to point on the first wagon to be sent
                    lts[id].w.w_w.p_wagon = p_wag;
                    lts[id].w.w_w.p_womim = p_womim;
                    MUTEX_LOCK(lts[id].w.w_w.p_womim->pfx.mutex);
                    lts[id].w.w_w.p_womim->pfx.counter++;
                    MUTEX_UNLOCK(lts[id].w.w_w.p_womim->pfx.mutex);
                }
                // We adapt len
                lts[id].w.len += p_wag->header.len;
            }
        }
    }

    lts[id].stamp.round = (char) round;
    MUTEX_LOCK(mutexWagonToSend);
    if (firstMsg(wagonToSend->p_wagon) != NULL ) {
        wagonToSend->p_wagon->header.round = round;

        // We add a wiw (corresponding to this p_wag) to wagonToSend
        wiw *wi = malloc(sizeof(wiw));
        assert(wi != NULL);
        *wi = *wagonToSend;
        // We do not need to lock wagonToSend->p_wagon->pfx.mutex
        // as we are for the moment alone to access to
        // wagonToSend->p_wagon->pfx.counter
        wagonToSend->p_womim->pfx.counter++;
        if (requiredOrder != CAUSAL_ORDER) {
            // Thus (requiredOrder == TOTAL_ORDER) || (requiredOrder == UNIFORM_TOTAL_ORDER))
            listAppend(unstableWagons[id][round], wi);
        } else {
            bqueueEnqueue(wagonsToDeliver, wi);
        }

        lts[id].p_wtosend = wagonToSend;

        wagonToSend = newWiw();
    }
    MUTEX_UNLOCK(mutexWagonToSend);
    pthread_cond_signal(&condWagonToSend);

    lts[id].stamp.lc = p_womim->msg.body.train.stamp.lc + 1;
}