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

pthread_mutex_t resource[5];
char res_str[] = "00000";

int pick(){return rand()%5;}
int pick2(){return rand()%2+1;}

void* t1 (void * p) {
  int r1, r2,test;
  while(1) {
    r1=pick(); r2=pick();
    sleep(pick2());

    /* The cuase for the deadlock is that both threads can randomly choose the same resources and they do not unlock teir recourse it has locked.
     * Therefore the threads will wait for eachother, but noone will let go of their resource.
     * My soloution is to trylock the resource instead, and if its used it will unlock any resource it has locked.
     * With this soloution the threads can still randomly choose the same resource but if it finds that it is already used it will unlock any resource it is using.
     * This prohibits deadlock from occouring beacuse the threads will not wait for a recourse that is being used.
     */

    if(!pthread_mutex_trylock(&resource[r1])){
        //if one of the resources are locked the thread will still do its standard procedure with the one it got
        res_str[r1]='1';
        if(!pthread_mutex_trylock(&resource[r2])){
            res_str[r2]='1';
            sleep(pick2());
            res_str[r1]='0';
            res_str[r2]='0';
            pthread_mutex_unlock(&resource[r1]);
            pthread_mutex_unlock(&resource[r2]);
        }
        else{
            //if one of the resources are locked the thread will still do its standard procedure with the one it got
            sleep(pick2());
            res_str[r1]='0';
            pthread_mutex_unlock(&resource[r1]);
            continue;
        }
    }
    else
        continue;

  }
}

void* t2 (void * p) {
  int r1, r2;
  while(1) {
    r1=pick(); r2=pick();
    sleep(pick2());
    if(!pthread_mutex_trylock(&resource[r1])){
        res_str[r1]='2';
        if(!pthread_mutex_trylock(&resource[r2])){
            res_str[r2]='2';
            sleep(pick2());
            res_str[r1]='0';
            res_str[r2]='0';
            pthread_mutex_unlock(&resource[r1]);
            pthread_mutex_unlock(&resource[r2]);
        }
        else{
            sleep(pick2());
            res_str[r1]='0';
            pthread_mutex_unlock(&resource[r1]);
            continue;
        }
    }
  }
}

main() {
  int i=0,n;
  pthread_t id1, id2;
  pthread_create(&id1,NULL,&t1,NULL);
  pthread_create(&id2,NULL,&t2,NULL);
  while(i++<30)
  {
    sleep(1);
    printf("%2d: %s\n", i, res_str);
  }
}
