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

#define N 10 // nombre de threads

int nb_phase_1 = 0;   /* nb de thread ayant terminé la phase 1 */
pthread_mutex_t m; /* verrou pour protéger nb1 */

sem_t s_attente; /* pour bloquer les threads ayant fini la phase 1 */

void* f(void* args){
    char* nom = (char*) args;
    sleep((rand() % 100) * 0.05);
    printf("%s: phase1\n", nom);
    pthread_mutex_lock(&m);
    nb_phase_1 += 1;
    if (nb_phase_1 == N) {
        printf("%s: je suis le dernier ... je débloque les autres \n", nom);
        for (int i = 0; i < N; i += 1) {
            sem_post(&s_attente);
        }
    }
    pthread_mutex_unlock(&m);

    printf("%s: ... en attente ... \n", nom);
    sem_wait(&s_attente); // j'attends d'être débloqué par le dernier thread
    sleep((rand() % 100) * 0.05);
    printf("%s: phase2 \n", nom);

    return NULL;
}


int main() {
    srand(time(NULL));
    char noms[N][2] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}; // noms des threads

    pthread_mutex_init(&m, NULL);
    sem_init(&s_attente, 0, 0);
    
    pthread_t t[N];
    for (int i = 0; i < N; i +=1){
        pthread_create(&t[i], NULL, f, (void*) noms[i]);
    }
    for (int i = 0; i < N; i +=1){
        pthread_join(t[i], NULL);
    }
    return 0;
}