#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define N 10

pthread_mutex_t lock;
pthread_cond_t  cond;

int resources= 2; //diathesimoi poroi gia eksipiretisi paraggeliwn taftoxrona
int id[N];

void *order(void *x){

    int id = *(int *)x;
    int rc;
    printf("H paraggelia %d xekinhse\n",id);

    rc = pthread_mutex_lock(&lock);
    while (resources == 0) { //otan den exoume allous diathesimous porous, perimenoume (adranes nima)
        printf("H paraggelia %d den brike diathesimo poro. Blocked...\n", id);
        rc = pthread_cond_wait(&cond, &lock); //perimene adranes nima mexri na ginei signal to cond variable
    }
	printf("H paraggelia %d eksipiretitai.\n", id);
    resources--; //meiwnoume kata 1 tous diathesimous porous giati mas eksipiretei 1 poros tin paraggelia
    rc = pthread_mutex_unlock(&lock);

    sleep(5); //kane kapoia douleia me ton poro

    rc = pthread_mutex_lock(&lock);
    printf("H paraggelia %d eksipiretithike epitixos! \n", id);
    resources++; //meiwnoume kata 1 tous diathesimous porous giati teleiwse i paraggelia
    rc = pthread_cond_signal(&cond); // kanoume signal to condition variable gia na ksipnisoume kapio nima pou perimenei apo to while loop (cond_wait)
    rc = pthread_mutex_unlock(&lock);

    pthread_exit(NULL);
}


int main()  {

    int rc;
    pthread_t threads[N];

    //arxikopiisi mutex kai cond variable me default attributes
    pthread_mutex_init(&lock, NULL);
    pthread_cond_init(&cond, NULL);

    for (int i = 0; i < N; i++) {
        id[i] = i+1;
        printf("Main: dhmioyrgia nhmatos %d\n", i+1);
    	rc = pthread_create(&threads[i], NULL, order, &id[i]);
    }

    //join ola ta threads
    for (int i = 0; i < N; i++) {
        pthread_join(threads[i], NULL);
    }

    //katastrofi mutex lock kai condition variable sto telos
    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&cond);

    return 0;
}
