Esempio n. 1
0
/*
 * Pipeline broadcast. This protocol takes 1 turn to broadcast, the node
 * performing the broadcast sends the message to the next note, which in turn
 * transmits the message to its neighbour and so on.
 * Note that like every functions defined here, they have the type NodesFct.
 */
void PipelineBroadcast(int id, Message m){
    char* event;
    Message msg, fwd;
    int neighbor;

    // Event Rules
    while((event = getNextExternalEvent(id)) != NULL){
        printf("event received %i %s\n",id, event); 
        // Read the first event
        if(0 == strcmp(event, "broadcast")){
            neighbor = (id + 1) % getNbNodes();
            msg = initMessage("Hello\0", id, id, neighbor);
            Send(msg);
            deliver(msg,id);
        }
        free(event);
    }

    // Message Rules
    if(NULL != m){
        deliver(m, id);

        // Forward the message if need be
        neighbor = (id + 1) % getNbNodes();
        if(neighbor != m->origin){
            fwd = initMessage(m->msg, m->origin, id, neighbor);
            Send(fwd);
        }

        // Free the local message
        deleteMessage(m);
    }
}
Esempio n. 2
0
/*
 * Basic broadcast. The broadcast takes N turns, all sends are done by the
 * same node (one at each turn).
 * Note that like every functions defined here, they have the type NodesFct.
 */
void BasicBroadcast(int id, Message m){
    char* event;
    Message msgOut;
    int i;

    //Events Rules
    while((event = getNextExternalEvent(id)) != NULL){
        printf("event received %d %s\n", id, event); 
        //Read the first event
        if(!strcmp(event, "broadcast")){
            //start a basic broadcast:
            //send hello to every nodes
            for(i = 0; i < getNbNodes(); i++){
                msgOut = initMessage("Hello\0", id, id, i);
                if(i != id){
                    Send(msgOut);
                } else {
                    deliver(msgOut,id);
                    deleteMessage(msgOut);
                }
            }
        }
        free(event);
    }

    //Message Rules
    if(NULL != m){
        deliver(m,id);
        deleteMessage(m);
    }
}
Esempio n. 3
0
AdjacencyMatrix::~AdjacencyMatrix()
{
    for(int edgeIter=0; edgeIter<getNbNodes(); edgeIter++)
    {
        for(int edgeIter2=0; edgeIter2<getNbNodes(); edgeIter2++)
        {
            Edge* ret = this->get(edgeIter,edgeIter2);
            if(ret != nullptr)
            {
                if(ret->isOriented())
                    set(edgeIter2,edgeIter,nullptr);
                delete ret;
            }
        }
    }
}
Esempio n. 4
0
/*
 * Total Order Broadcast with good throughput.
 * Note that like every functions defined here, they have the type NodesFct.
 */
void TOBThroughputRodBroadcast(int id, Message m){
    char* event;
    Message msgOut;

    //Events Rules
    while((event = getNextExternalEvent(id)) != NULL){
        printf("Event received %d %s\n", id, event); 
        //Read the first event
        if(!strcmp(event, "broadcast")){
            if(0 == id){
                // The broadcast is your own, deliver
                msgOut = initMessage("Hello\0", id, id, id);
                deliver(msgOut, id);
                deleteMessage(msgOut);
                // Pass the message to your successor

                if(1 != getNbNodes()){
                    msgOut = initMessage("Hello\0", 0, 0, 1);
                    Send(msgOut);
                }
            } else {
                // Send the message to process 0
                msgOut = initMessage("Hello\0", id, id, 0);
                Send(msgOut);
            }
        }
        free(event);
    }

    // Message Rules
    if(NULL != m){
        if(0 == id)
            printf("0 receives a message to relay from %i\n", m->sender);

        deliver(m, id);

        // If not the last of the pipeline...
	if(id != getNbNodes() - 1){
            // Transfer the message to you successor
            msgOut = initMessage(m->msg, m->origin, id, id + 1 % getNbNodes());
            Send(msgOut);
	}

        deleteMessage(m);
    }
}
Esempio n. 5
0
/*
 * Tree broadcast. This protocol needs log(NbNodes) turn to broadcast.
 * Every node sends to its succesors.
 * Note that like every functions defined here, they have the type NodesFct.
 */
void TreeBroadcast(int id, Message m){
    char* event;
    Message msgOut;
    int nTurn;

    //Events Rules
    while((event = getNextExternalEvent(id)) != NULL){
        printf("Event received %d %s\n", id, event); 
        //Read the first event
        if(!strcmp(event, "broadcast")){
            //start a tree broadcast:
            //Iniatialize the message
            for(nTurn = 0; nTurn < log2(getNbNodes()); nTurn++){
                //at the first step of the tree broadcast, we send a message
                //to our successor
                msgOut = initMessage("Hello\0", id, id, (int)(pow(2,nTurn)+id)%getNbNodes());
                Send(msgOut);
            }
            // Deliver the message localy
            msgOut = initMessage("Hello\0", id, id, id);
            deliver(msgOut,id);
            deleteMessage(msgOut);
        }
        free(event);
    }

    //Message Rules
    if(NULL != m){
        deliver(m,id);
        //at a step n, a message is sent at a distance 2^n
        //the distance is not exactly the difference between the sender and the
        //receiver id because of the mod N
        if(m->sender < m->receiv)
            nTurn=log2(m->receiv-m->sender);
        else
            nTurn=log2(getNbNodes()-m->sender+m->receiv);
        //this turn is done, let's do the others
        //now we can send all the others messages
        for(nTurn++; nTurn<log2(getNbNodes()); nTurn++){
            msgOut = initMessage(m->msg, m->origin, id, ((int)(pow(2,nTurn)+id))%getNbNodes());
            Send(msgOut);
        }
        deleteMessage(m);
    }
}
Esempio n. 6
0
/*
 * Total Order Broadcast with good latency.
 * Note that like every functions defined here, they have the type NodesFct.
 */
void TOBLatencyBroadcast(int id, Message m){
    char* event;
    Message msgOut;
    int i;

    //Events Rules
    while((event = getNextExternalEvent(id)) != NULL){
        printf("Event received %d %s\n", id, event); 
        //Read the first event
        if(!strcmp(event, "broadcast")){
            if(0 == id){
                // The broadcast is your own, deliver
                msgOut = initMessage("Hello\0", id, id, id);
                deliver(msgOut, id);
                deleteMessage(msgOut);
                // Pass the message to your childs
                for(i = 1; i < getNbNodes(); i *= 2){
                    msgOut = initMessage("Hello\0", id, id, i);
                    Send(msgOut);
                }
            } else {
                // Send the message to process 0
                msgOut = initMessage("Hello\0", id, id, 0);
                Send(msgOut);
            }
        }
        free(event);
    }

    // Message Rules
    if(NULL != m){
        if(0 == id)
            printf("0 receives a message to relay from %i\n", m->sender);

        deliver(m, id);

        for(i = 2 * id + 1; i < getNbNodes(); i *= 2){
            msgOut = initMessage(m->msg, m->origin, id, i);
            Send(msgOut);
        }

        deleteMessage(m);
    }
}
Esempio n. 7
0
/*
 * Total Order Broadcast with good throughput.
 * Note that like every functions defined here, they have the type NodesFct.
 */
void TOBThroughputBroadcast(int id, Message m){

    PipelineAckData_t data;
    int argSize, ackOrigin;
    char *event, *eventArg, *msgTxt;
    Message mOut;
    NumberedMessage NumMsg, temp;

    if((data=(PipelineAckData_t)getData(id))==NULL){
        //Initialization

        if((data=malloc(sizeof(struct _PipleineAckData_t)))==NULL){
            fprintf(stderr,"malloc fail at TOBThroughputBroadcast\n");
            exit(EXIT_FAILURE);
        }

        data->clock=0;
        data->next=(id+1)%getNbNodes();
        //        data->pred=(id==0)?getNbNodes()-1:id-1;
        data->pending=newSortedList(NumberedMsgComp);
        setData(id,data);
    }

    if(m==NULL){
        // Event Rules
        if((event = getNextExternalEvent(id)) != NULL){
            printf("event received %i %s\n",id, event); 
            // Read the first event
            if(event==strstr(event, "broadcast")){
                //there is an event : increment the clock
                data->clock++;
                //event is someting like broadcast <string>
                if((eventArg=malloc(sizeof(char)*maxArgSize))==NULL){
                    fprintf(stderr,"malloc fail at TOBThroughputBroadcast\n");
                    exit(EXIT_FAILURE);
                }
                if(1>sscanf(event, "broadcast %s", eventArg)){
                    sscanf("hello","%s",eventArg);
                }
                //eventArg is either the string to broadcast, or "hello"
                argSize=strlen(eventArg);
                if((msgTxt=malloc((intToStringSize+1+argSize)*sizeof(char)))==NULL){
                    fprintf(stderr,"malloc fail at TOBThroughputBroadcast\n");
                    exit(EXIT_FAILURE);
                }
                sprintf(msgTxt, "%d ",data->clock);
                strncat(msgTxt, eventArg, argSize); 
                //Now the message text have the format: clk <arg>
                if((NumMsg=malloc(sizeof(struct _NumberedMessage)))==NULL){
                    fprintf(stderr,"malloc fail at TOBThroughputBroadcast\n");
                    exit(EXIT_FAILURE);
                }
                NumMsg->clk=data->clock;
                //waiting for 1 ack
                //creating the actual message
                NumMsg->m=initMessage(msgTxt,id,id,data->next);
                free(msgTxt);
                NumMsg->origin=id;
                if(data->next==id){
                    //we are the only process of the system
                    deliver(NumMsg->m,id);
                    free(NumMsg->m->msg);
                    free(NumMsg->m);
                    free(NumMsg);
                }else{
                    //and send it
                    Send(copyMessage(NumMsg->m));
                    //Finally store the numbered msg in the pending list
                    AddSorted(NumMsg,data->pending);
                }
            }
            free(event);
        }

    }else{
        // Message Rules
        if((NumMsg=malloc(sizeof(struct _NumberedMessage)))==NULL){
            fprintf(stderr,"malloc fail at TOBThroughputBroadcast\n");
            exit(EXIT_FAILURE);
        }

        //this is a new message at the format:
        //clock <text> where text is either ack or the text of the
        //message
        //We have to parse the clock of the broadcast
        extractInt(m->msg, &(NumMsg->clk));
        NumMsg->origin=m->origin;
        //don't forget to update the clock
        data->clock=MAX(NumMsg->clk,data->clock)+1;

        if(strstr(m->msg,"ack")==NULL){
            printf("%s received by %d from %d but not delivered yet\n", m->msg, id, m->sender);
            //m is an actual message
            NumMsg->m=m;
            if(m->origin!=data->next){
                //We need to forward the message
                mOut=initMessage(m->msg,m->origin,id,data->next);
                Send(mOut);
                AddSorted(NumMsg,data->pending);
            }else{
                AddSorted(NumMsg,data->pending);
                //we deliver all the older messages
                mOut=NULL;
                while((temp=getFirst(data->pending))!=NULL && NumMsg!=NULL && NumberedMsgComp(temp,NumMsg)<=0){
                    //we remove the message from the pending list
                    RemoveFirst(data->pending);
                    if(!NumberedMsgComp(temp,NumMsg)){
                        //to ensure we stop after that
                        NumMsg=NULL;
                    }
                    //prepare an ack
                    if(temp->origin!=id){
                        if(mOut!=NULL){
                            free(mOut);
                        }
                        mOut=Ack(temp->clk,temp->origin,id,data->next);
                    }
                    //deliver
                    deliver(temp->m,id);
                    //we can free the message
                    free(temp->m->msg);
                    free(temp->m);
                    free(temp);
                }
                //if we have managed to deliver a message
                //we acknowleged the older message delvered
                if(mOut){
                    Send(mOut);
                }
            }

        }else{
            //this is an ack
            printf("%s received by %d from %d origin %d\n", m->msg, id, m->sender, m->origin);
            //we deliver all the older messages
            mOut=NULL;
            while((temp=getFirst(data->pending))!=NULL && NumMsg!=NULL && NumberedMsgComp(temp,NumMsg)<=0){
                //we remove the message from the pending list
                RemoveFirst(data->pending);
                //prepare an ack
                ackOrigin=((temp->origin+getNbNodes()-1)%getNbNodes());
                if(ackOrigin!=data->next){
                    if(mOut!=NULL){
                        free(mOut);
                    }
                    mOut=Ack(temp->clk,temp->origin,id,data->next);
                }
                //deliver
                deliver(temp->m,id);
                //we can free the message
                free(temp->m->msg);
                free(temp->m);
                free(temp);
            }
            //if we have managed to deliver a message
            //we acknowleged the older message delvered
            ackOrigin=((NumMsg->origin+getNbNodes()-1)%getNbNodes());
            if(mOut){
                Send(mOut);
            }else if(Size(data->pending)==0 && ackOrigin!=data->next){
                //we haven't be able to deliver a message because our pending
                //list is empty, but the message may be blocked in someon else
                //queue so we forward the ack
                Send(Ack(NumMsg->clk,NumMsg->origin,id,data->next));
            }
            // Free the local message
            free(m->msg);
            free(m);
        }
    }

}