#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;
  while(1) {
    r1=pick(); r2=pick();
    sleep(pick2());
    pthread_mutex_lock(&resource[r1]);
    if(!pthread_mutex_trylock(&resource[r2])){
    res_str[r1]='1';
    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{
       pthread_mutex_unlock(&resource[r1]);
    }
  }
}

/*
Jag tyckte att mutex_trylock skulle passa bättre i denna situation
eftersom att när man kollar på vad som sker vid deadlocken är det så att 
trådarna har en random resurs att få tag i mellan 0 och 4. Om ett utav
resurserna är upptagna kommer tråden att vara fast och då denna tråd inte
får försöka ta en annan resurs. Enligt manualen (pthread_mutex_trylock)
står det att trylock är ekvivalent med mutex_lock men skillnaden är
att trylock håller koll om resursen redan är tagen eller inte, om 
resursen inte är tagen returnerar trylock "0", annars vid error ett 
negativt värde. När man väljer att göra en trylock i detta fall kommer
tråden inte alls ta något av resurserna vilket är därför man kan se i 
några av körningarna då ingen resurs alls är tagen ibland då de har 
skippat pga att trylock inte har tillåtit tråden att greppa tag i resurs.


*/
void* t2 (void * p) {
  int r1, r2;
  while(1) {
    r1=pick(); r2=pick();
    sleep(pick2());
    pthread_mutex_lock(&resource[r1]);
   if(!pthread_mutex_trylock(&resource[r2])){
    res_str[r1]='2';
    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{
       pthread_mutex_unlock(&resource[r1]);
	
    }
  }
}

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);
  }
}
