Open In App

Raymond’s tree based algorithm

Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisite – Mutual exclusion in distributed systems 
Raymond’s tree based algorithm is lock based algorithm for mutual exclusion in a distributed system in which a site is allowed to enter the critical section if it has the token. In this algorithm, all sites are arranged as a directed tree such that the edges of the tree are assigned direction towards the site that holds the token. Site which holds the token is also called root of the tree. 
Data structure and Notations: 

  • Every site Si keeps a FIFO queue, called request_q 
    This queue stores the requests of all neighbouring sites that have sent a request for the token to site Si but have not yet been sent token. A non-empty request_q at any site indicates that the site has sent a REQUEST message to the root node.
    Every site Si has a local variable, called holder 
    This variable points to an immediate neighbour node on a directed path to the root node.

Algorithm:  

To enter Critical section: 

When a site Si wants to enter the critical section it sends a REQUEST message to the node along the directed path to the root, provided it does not hold the token and its request_q is empty. After sending REQUEST message it add its request to its request_q.
when a site Sj on the path to the root receives the REQUEST message of site Si, it places the REQUEST in its request_q and sends the REQUEST message along the directed path to the root, if it has not sent any REQUEST message for previously received REQUEST message.
When the root site Sr( having token) receives the REQUEST message, it sends the token to the requesting site and sets its holder variable to point at that site.
On receiving the token, Site Sj deletes the top entry from its request_q and sends the token to the site indicated by deleted entry. holder variable of Site Sj is set to point at that site. 
After deleting the topmost entry of the request_q, if it is still non-empty Site Sj sends a REQUEST message to the site indicated by holder variable in order to get token back.
To execute the critical section: 

Site Si executes the critical section if it has received the token and its own entry is at the top of its request_q.
To release the critical section: 
After finishing the execution of the critical section, site Si does the following: 

If its request_q is non-empty, then it deletes the top most entry from its <request_q and then it sends the token to that site indicated by deleted entry and also its holder variable is set to point at that site.
After performing above action, if the request_q is still non-empty, then site Si sends a REQUEST message to the site pointed by holder variable in order to get token back

Message Complexity: 
In the worst case, the algorithm requires 2 * ( Longest path length of the tree ) message invocation per critical section entry. If all nodes are arranged in a straight line then the longest path length will be N – 1 and thus the algorithm will require 2 * (N -1) message invocation for critical section entry. However, if all nodes generates equal number of REQUEST messages for the privilege, the algorithm will require approximately 2*N / 3 messages per critical section entry. 

Drawbacks of Raymond’s tree based algorithm:  

can cause starvation: Raymond’s algorithm uses greedy strategy as a site can executes the critical section on receiving the token even when its request is not on the top of the request queue. This affect the fairness of the algorithm and thus can cause in starvation.

Performance:

Synchronization delay is (T * log N )/ 2, because the average distance between two sites to successively execute the critical section is (Log N)/2. Here T is maximum message transmission time.
In heavy load conditions, the synchronization delay become T because a site executes the critical section every time the token is transferred.
The message complexity of this algorithm is O(log N) as the average distance between any two nodes in a tree with N nodes is log N
Deadlock is impossible

The Code for visualising Raymond Tree Based Algorithm is given below:

C++




//Contributed by Anuj Kumar Sahu
#include <stdio.h>
#include <stdlib.h>
// Define Structure for Node
struct node {
    int id;
    int holderval;
    struct node* l;
    struct node* r;
    int require[20];
};
typedef struct node node;
//Function for inorder Traversal
void TraversalInorder(node* roonodeT)
{
 
    if (roonodeT == NULL) {
        return;
    }
    TraversalInorder(roonodeT->l);
    printf("%d  %d\n", roonodeT->id, roonodeT->holderval);
    TraversalInorder(roonodeT->r);
}
 
void token(node* roonodeT, int NodeCS)
{
 
    if (NodeCS == roonodeT->id) {
        printf("%d\n", roonodeT->id);
        roonodeT->holderval = roonodeT->id;
        return;
    }
    else if (NodeCS < roonodeT->id) {
        roonodeT->holderval = (roonodeT->l)->id;
        printf("%d->", roonodeT->id);
        roonodeT = roonodeT->l;
 
        token(roonodeT, NodeCS);
    }
    else if (NodeCS > roonodeT->id) {
        roonodeT->holderval = (roonodeT->r)->id;
        printf("%d->", roonodeT->id);
        roonodeT = roonodeT->r;
        token(roonodeT, NodeCS);
    }
}
 
// Function to Insert Node
void NodeTinsert(node* nodeNew, node* roonodeT)
{
    if (nodeNew->id > roonodeT->id) {
        if (roonodeT->r == NULL) {
            roonodeT->r = nodeNew;
            nodeNew->holderval = roonodeT->id;
        }
        else
            NodeTinsert(nodeNew, roonodeT->r);
    }
 
    if (nodeNew->id < roonodeT->id) {
        if (roonodeT->l == NULL) {
            roonodeT->l = nodeNew;
            nodeNew->holderval = roonodeT->id;
        }
        else
            NodeTinsert(nodeNew, roonodeT->l);
    }
}
 
// Driver Function
int main()
{
    node *roonodeT = NULL, *nodeNew = NULL, *node1;
    int i;
    // Value to be given below
    int n = 5;
    int nodeT = 3;
    int idValue;
    int arr[5] = { 1, 2, 3, 4, 5 };
    int NodeCS, option;
    roonodeT = (struct node*)malloc(sizeof(node));
    node1 = (struct node*)malloc(sizeof(node));
    roonodeT->id = nodeT;
    roonodeT->r = roonodeT->l = NULL;
    roonodeT->holderval = roonodeT->id;
    for (i = 0; i < n; i++) {
        idValue = arr[i];
        nodeNew = (struct node*)malloc(sizeof(node));
        nodeNew->l = nodeNew->r = NULL;
        if (i == nodeT)
            i++;
        nodeNew->id = idValue;
 
        NodeTinsert(nodeNew, roonodeT);
    }
    TraversalInorder(roonodeT);
    NodeCS = 2;
    token(roonodeT, NodeCS);
    return -1;
}


Output

1  3
2  1
3  3
4  3
3->1->2


Last Updated : 09 May, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads