/*Jag gjorde resursen som trådarna försöker ta delad. Sedan kommer trådarna göra trylock istället för lock, för att kontrollera ifall det verkligen går att locka den resursen. Enligt man:

       The pthread_mutex_trylock() function shall return zero if a lock on the
       mutex object referenced by mutex is acquired. Otherwise, an error  num‐
       ber is returned to indicate the error.

	EBUSY  The mutex could not be acquired because it was already locked.

Deadlock kan uppstå när trådar försöker ta kontroll över varandras resurser i ett cykliskt mönster.

*/
#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;}
int r1, r2;

void* t1 (void * p) {
  while(1) {
    r1=pick(); r2=pick();
    sleep(pick2());
    
    pthread_mutex_trylock(&resource[r1]);
    res_str[r1]='1';
    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]);
  }
}

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

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