Andrian Ioan
Andrian Ioan

Reputation: 3

Recursion function and pthreads

I recently started working on pthreads and stuck with a problem. So, I have a binary tree topology, 15 nodes (0->14 nodeIDs) and I 've made 4 pthreads for the nodes 3,4,5 and 6 (didn't want to create more for an e.g.). So, each thread created is trying to reach its parent node to lock the node and to increase the value of a global variable in there. To do this I've created a mutex for each node in the node structure and used pthread_mutex_trylock conditions- otherwise I had them do whatever, e.g. finishing and not do the job or misbehave with each other. So, the thing is that my program crashes when I call a function for each thread calling itself. The code can be seen below. If I change the name of the function testExclusion to testExclusion22 works fine, otherwise the program continues going without stopping. Same thing happens if I have a limited number of self-calls e.g. a 3 times loop -> see testFunction(). So my question is, what is wrong? Do I have something written wrong or this is not supported and if it is how can I do so? Thanks a lot!

// main.c

//  Threads_Extended


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

int globalVariable;
pthread_mutex_t global;

typedef struct node {    
    int value;
    int nodeID;
    struct node *parent;

    pthread_mutex_t nodeMutex;
} node_t ;


void initialize_node(node_t *node,node_t *next, int nodeIdentity)
{   
    node->nodeID=nodeIdentity;    
    node->parent = next;
    node->value=0;   
}


void printingFunction(void){
    printf("This is for testing ONLY!");

    //for (int i=0; i<3; i++) {
    printingFunction();
    //}
}


void testExclusion22(node_t *node, node_t *next)
{   
    int locked=0;    
    int locked2=0;

    printf("I am thread %d and I am trying to lock node %d!\n", node->nodeID, next->nodeID);

    while (locked!=1){
        if(pthread_mutex_trylock(&next->nodeMutex)==0){
            printf("I am thread %d and I am increasing the global value!\n", node->nodeID);

            while(locked2!=1){
                if ((pthread_mutex_trylock(&global))==0){
                    globalVariable++;
                    printf("Global variable's value is: %d!\n", globalVariable);
                    pthread_mutex_unlock(&global);
                    locked2=1;
                }
            }

            printf("I am thread %d and I am releasing the node %d!\n", node->nodeID, next->nodeID);
            pthread_mutex_unlock(&next->nodeMutex);
            locked=1;
        }
        else
            printf("I am thread %d and I was not able to lock next node %d!\n", node->nodeID, next->nodeID);
}

    printingFunction();
    // testExclusion(node, node->parent);
}

void testExclusion(node_t *node, node_t *next)
{
    int locked=0;
    int locked2=0;

    printf("I am thread %d and I am trying to lock node %d!\n", node->nodeID, next->nodeID);

    while (locked!=1){
        if(pthread_mutex_trylock(&next->nodeMutex)==0){
            printf("I am thread %d and I am increasing the global value!\n", node->nodeID);

            while(locked2!=1){
                if ((pthread_mutex_trylock(&global))==0){
                    globalVariable++;
                    printf("Global variable's value is: %d!\n", globalVariable);
                    pthread_mutex_unlock(&global);
                    locked2=1;
                }
            }

            printf("I am thread %d and I am releasing the node %d!\n", node->nodeID, next->nodeID);
            pthread_mutex_unlock(&next->nodeMutex);
            locked=1;
        }
        else
            printf("I am thread %d and I was not able to lock next node %d!\n", node->nodeID, next->nodeID);
    }

    testExclusion22(node, node->parent);
   // testExclusion(node, node->parent);
}



void *PrintHello(void *node)
{
    node_t *tempNode=node;
    pthread_mutex_init(&global, NULL);

    printf("Hello World! It's me, thread of node # %d!\n", (tempNode->nodeID));

    testExclusion(tempNode, tempNode->parent);   
    pthread_exit(NULL);
}


int main (int argc, char *argv[])
{

    node_t *nodes = malloc(15 * sizeof(node_t));

    int rc;
    int simCounter;

    int i;
    int j=0;
    int n=0;

    globalVariable=0;

    for (i=0; i<7; i++) {
        if (i==0){
            initialize_node(&nodes[i],NULL,i);
            printf("Node %d has been created! Node %d is the source root! \n\n", nodes[i].nodeID,nodes[i].nodeID);
        }
        else{
            if ((n%2)==0){
                initialize_node(&nodes[i],&nodes[j],i);
                printf("Node %d has been created with Node %d as a parent! \n\n", nodes[i].nodeID,nodes[j].nodeID);
                n++;
            }
            else
            {
                initialize_node(&nodes[i],&nodes[j],i);
                printf("Node %d has been created with Node %d as a parent! \n\n", nodes[i].nodeID,nodes[j].nodeID);
                j++;
                n++;
            }
        }
    }

    simCounter=2;

    for(i=0; i<7; i++)
        pthread_mutex_init(&nodes[i].nodeMutex, NULL);

    for (j=1; j<(simCounter+1); j++){
        pthread_t *threads = malloc(4 * sizeof(pthread_t));

        for(i=0; i<4; i++){
            printf("In main: creating thread %d\n", i);
            nodes[i].nodeID=i;
            rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&nodes[i+3]);
            if (rc){
                printf("ERROR; return code from pthread_create() is %d\n", rc);
                exit(-1);
            }
            pthread_mutex_destroy(&nodes[i+3].nodeMutex);
        }
        for(i=0; i<4; i++)
            pthread_join(threads[i], NULL);

        printf("I am back in main!\n\n\n");

        free(threads);
        pthread_mutex_destroy(&global);
    }

    free(nodes);
    pthread_exit(NULL);
}

Upvotes: 0

Views: 1253

Answers (1)

Tobia
Tobia

Reputation: 18811

Your printingFunction() is forever calling itself, without any exit condition:

void printingFunction() {
    printf("This is for testing ONLY!");
    printingFunction();
}

Upvotes: 1

Related Questions