Esempio n. 1
0
static THREAD_RETURN returnChannelMain(void *args) {
    struct returnChannel *returnChannel = (struct returnChannel *) args;
    fd_set read_set;
    int r=0;
    FD_ZERO(&read_set);

    while(1) {
        struct sockaddr_in from;
        int clNo;
        int pos = pc_getConsumerPosition(returnChannel->freeSpace);
        pc_consumeAny(returnChannel->freeSpace);
        do {
            struct timeval tv;
            if(returnChannel->stopIt)
                return 0;
            FD_SET(returnChannel->rcvSock,&read_set);
            tv.tv_sec=0;
            tv.tv_usec=100;
            r = select(returnChannel->rcvSock+1,
                       &read_set, NULL, NULL, &tv);
        } while(r==0);

        RECV(returnChannel->rcvSock, 
             returnChannel->q[pos].msg, from,
             returnChannel->config->portBase);
        clNo = udpc_lookupParticipant(returnChannel->participantsDb, &from);
        if (clNo < 0) { 
            /* packet from unknown provenance */
            continue;
        }
        returnChannel->q[pos].clNo = clNo;
        pc_consumed(returnChannel->freeSpace, 1);
        pc_produce(returnChannel->incoming, 1);
    }
}
Esempio n. 2
0
static int ackSlice(struct slice *slice, struct net_config *net_config,
                    struct fifo *fifo, sender_stats_t stats)
{
    if(slice->state == SLICE_ACKED)
        /* already acked */
        return 0;
    if(!(net_config->flags & FLAG_SN)) {
        if(net_config->discovery == DSC_DOUBLING) {
                net_config->sliceSize += net_config->sliceSize / 4;
           if(net_config->sliceSize >= net_config->max_slice_size) {
               net_config->sliceSize = net_config->max_slice_size;
               net_config->discovery = DSC_REDUCING;
           }
           udpc_logprintf(udpc_log, "Doubling slice size to %d\n", 
                          net_config->sliceSize);
       }
    }
    slice->state = SLICE_ACKED;
    pc_produce(fifo->freeMemQueue, slice->bytes);

    /* Statistics */
    senderStatsAddBytes(stats, slice->bytes);

    if(slice->bytes) {
        displaySenderStats(stats, 
                           net_config->blockSize, net_config->sliceSize);
    }
    /* End Statistics */

    return 0;
}
Esempio n. 3
0
void udpc_initFifo(struct fifo *fifo, int blockSize)
{
    fifo->dataBufSize = blockSize * 4096;
    fifo->dataBuffer = xmalloc(fifo->dataBufSize+4096);
    fifo->dataBuffer += 4096 - (((unsigned long)fifo->dataBuffer) % 4096);

    /* Free memory queue is initially full */
    fifo->freeMemQueue = pc_makeProduconsum(fifo->dataBufSize, "free mem");
    pc_produce(fifo->freeMemQueue, fifo->dataBufSize);

    fifo->data = pc_makeProduconsum(fifo->dataBufSize, "receive");
}
Esempio n. 4
0
static void initReturnChannel(struct returnChannel *returnChannel,
			      struct net_config *config,
			      int sock) {
    returnChannel->config = config;
    returnChannel->rcvSock = sock;
    returnChannel->freeSpace = pc_makeProduconsum(QUEUE_SIZE,"msg:free-queue");
    pc_produce(returnChannel->freeSpace, QUEUE_SIZE);
    returnChannel->incoming = pc_makeProduconsum(QUEUE_SIZE,"msg:incoming");

    pthread_create(&returnChannel->thread, NULL,
		   returnChannelMain, returnChannel);

}
Esempio n. 5
0
static THREAD_RETURN fecMain(void *args0)
{
    sender_state_t sendst = (sender_state_t) args0;

    slice_t slice;
    int sliceNo = 0;

    while(1) {
        /* consume free slice */
        slice = makeSlice(sendst, sliceNo++);
        /* do the fec calculation here */
        fec_encode_all_stripes(sendst,slice);
        pc_produce(sendst->fec_data_pc, 1);
    }
    return 0;
}
Esempio n. 6
0
static int freeSlice(sender_state_t sendst, struct slice *slice) {
    int i;
    i = slice - sendst->slices;
#if DEBUG
    flprintf("Freeing slice %p %d %d\n", slice, slice->sliceNo, i);
#endif
    slice->state = SLICE_PRE_FREE;
    while(1) {
        int pos = pc_getProducerPosition(sendst->free_slices_pc);
        if(sendst->slices[pos].state == SLICE_PRE_FREE)
            sendst->slices[pos].state = SLICE_FREE;
        else
            break;
        pc_produce(sendst->free_slices_pc, 1);
    }
    return 0;
}
Esempio n. 7
0
static int handleNextMessage(sender_state_t sendst,
                             struct slice *xmitSlice,
                             struct slice *rexmitSlice)
{
    int pos = pc_getConsumerPosition(sendst->rc.incoming);
    union message *msg = &sendst->rc.q[pos].msg;
    int clNo = sendst->rc.q[pos].clNo;

#if DEBUG
    flprintf("handle next message\n");
#endif

    pc_consumeAny(sendst->rc.incoming);
    switch(ntohs(msg->opCode)) {
        case CMD_OK:
            handleOk(sendst, 
                     findSlice(xmitSlice, rexmitSlice, ntohl(msg->ok.sliceNo)),
                     clNo);
            break;
        case CMD_DISCONNECT:
            handleDisconnect(sendst->rc.participantsDb, 
                             xmitSlice, rexmitSlice, clNo);
            break;          
        case CMD_RETRANSMIT:
#if DEBUG
            flprintf("Received retransmittal request for %ld from %d:\n",
                     (long) xtohl(msg->retransmit.sliceNo), clNo);
#endif
            handleRetransmit(sendst,
                             findSlice(xmitSlice, rexmitSlice,
                                       ntohl(msg->retransmit.sliceNo)),
                             clNo,
                             msg->retransmit.map,
                             msg->retransmit.rxmit);
            break;
        default:
            udpc_flprintf("Bad command %04x\n", 
                          (unsigned short) msg->opCode);
            break;
    }
    pc_consumed(sendst->rc.incoming, 1);
    pc_produce(sendst->rc.freeSpace, 1);
    return 0;
}
Esempio n. 8
0
int spawnNetSender(struct fifo *fifo,
                   int sock,
                   struct net_config *config,
                   participantsDb_t db,
                   sender_stats_t stats)
{
    int i;

    sender_state_t sendst = MALLOC(struct senderState);
    sendst->fifo = fifo;
    sendst->socket = sock;
    sendst->config = config;
    sendst->stats = stats;
#ifdef BB_FEATURE_UDPCAST_FEC
    if(sendst->config->flags & FLAG_FEC)
      sendst->fec_data =  xmalloc(NR_SLICES *
                                  config->fec_stripes * 
                                  config->fec_redundancy *
                                  config->blockSize);
#endif
    sendst->rc.participantsDb = db;
    initReturnChannel(&sendst->rc, sendst->config, sendst->socket);

    sendst->free_slices_pc = pc_makeProduconsum(NR_SLICES, "free slices");
    pc_produce(sendst->free_slices_pc, NR_SLICES);
    for(i = 0; i <NR_SLICES; i++)
        sendst->slices[i].state = SLICE_FREE;

#ifdef BB_FEATURE_UDPCAST_FEC
    if(sendst->config->flags & FLAG_FEC) {
        /* Free memory queue is initially full */
        fec_init();
        sendst->fec_data_pc = pc_makeProduconsum(NR_SLICES, "fec data");

        pthread_create(&sendst->fec_thread, NULL, fecMain, sendst);
    }
#endif

    pthread_create(&fifo->thread, NULL, netSenderMain, sendst);
    return 0;
}
Esempio n. 9
0
static THREAD_RETURN returnChannelMain(void *args) {
    struct returnChannel *returnChannel = (struct returnChannel *) args;

    while(1) {
	struct sockaddr_in from;
	int clNo;
	int pos = pc_getConsumerPosition(returnChannel->freeSpace);
	pc_consumeAny(returnChannel->freeSpace);

	RECV(returnChannel->rcvSock, 
	     returnChannel->q[pos].msg, from,
	     returnChannel->config->portBase);
	clNo = udpc_lookupParticipant(returnChannel->participantsDb, &from);
	if (clNo < 0) { 
	    /* packet from unknown provenance */
	    continue;
	}
	returnChannel->q[pos].clNo = clNo;
	pc_consumed(returnChannel->freeSpace, 1);
	pc_produce(returnChannel->incoming, 1);
    }
    return 0;
}