/* 
   This file is part of Practical Distributed Processing
   Copyright (C) 2006-2007 Phillip J. Brooke and Richard F. Paige
*/

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

/* Global declarations, including shared variable */

pthread_mutex_t mutex; 
int x = 0; 

void increase_x(void)
{
    int temp;

    /* Enter critical region */
    pthread_mutex_lock(&mutex);
    temp=x;
    temp+=1;
    x = temp;
    pthread_mutex_unlock(&mutex);
    /* Exit critical region */
}

void* ThreadBehaviour(void *argument)
{
    char *name = (char*)argument;
    if( name != NULL )
    {
      increase_x();
      printf("Value of x is %d in %s\n", x, name);
    }
    pthread_exit(NULL);
    return 0; /* Never reach this line. */
}

int main()
{
    pthread_t threadA, threadB;

    if (pthread_mutex_init(&mutex, NULL) < 0) 
    {
        perror("pthread_mutex_init failed");
        exit(EXIT_FAILURE);
    }

    if (pthread_create(&threadA, NULL, ThreadBehaviour, 
                        (void *)"Thread A") != 0) 
    {
        perror("pthread_create failed");
        exit(EXIT_FAILURE);
    }

    if (pthread_create(&threadB, NULL, ThreadBehaviour,
                        (void *)"Thread B") != 0) 
    {
        perror("pthread_create failed");
        exit(EXIT_FAILURE);
    }

    pthread_join(threadA, NULL);
    pthread_join(threadB, NULL);
    pthread_mutex_destroy(&mutex);
    
    return 0;
}        

