diff --git a/tp.c b/tp.c index 115b733c12137794713450f7f33203ebe78a2966..5c21837d6543d79818b8642e48cd87f8f8e73c53 100644 --- a/tp.c +++ b/tp.c @@ -4,116 +4,150 @@ #include <semaphore.h> #include <unistd.h> -#define SITES 10 -#define HABITANTS 100 -#define TRAJETS 10 -#define BORNES 10 #define CAMION_CAPACITE 4 typedef struct { sem_t velos; sem_t bornes; int velos_dispo; + pthread_mutex_t mutex; } Site; -Site sites[SITES]; -sem_t depot; +int SITES, HABITANTS, TRAJETS, BORNES; +Site *sites; pthread_mutex_t mutex_trajets = PTHREAD_MUTEX_INITIALIZER; -int trajets_effectues = 0; // Compteur des trajets terminés +int trajets_effectues = 0; int velos_depot = 0; +pthread_mutex_t mutex_velos_depot = PTHREAD_MUTEX_INITIALIZER; void *habitant(void *arg) { int id = *(int *)arg; int site_actuel = rand() % SITES; + free(arg); + for (int i = 0; i < TRAJETS; i++) { - sem_wait(&sites[site_actuel].velos); - printf("(GET) Habitant %d prend un vélo au site %d\n", id, site_actuel); - sem_post(&sites[site_actuel].bornes); - int site_suivant; - do { site_suivant = rand() % SITES; } while (site_suivant == site_actuel); - usleep((rand() % 1000 + 1000)); + printf("(GET) Habitant %d attend un vélo au site %d\n", id, site_actuel); + sem_wait(&sites[site_actuel].velos); + pthread_mutex_lock(&sites[site_actuel].mutex); + sites[site_actuel].velos_dispo--; + pthread_mutex_unlock(&sites[site_actuel].mutex); + printf("(GET) Habitant %d prend un vélo au site %d\n", id, site_actuel); + sem_post(&sites[site_actuel].bornes); + + + //usleep((rand() % 100 + 100)); + + printf("(PUT) Habitant %d attend d'avoir accès à une borne du site %d\n", id, site_actuel); sem_wait(&sites[site_suivant].bornes); + pthread_mutex_lock(&sites[site_suivant].mutex); + sites[site_suivant].velos_dispo++; + sem_post(&sites[site_suivant].velos); + pthread_mutex_unlock(&sites[site_suivant].mutex); printf("(PUT) Habitant %d dépose un vélo au site %d\n", id, site_suivant); - + site_actuel = site_suivant; - usleep((rand() % 1000 + 1000)); - } - free(arg); - // 🔹 Augmenter le compteur de trajets terminés - pthread_mutex_lock(&mutex_trajets); - trajets_effectues++; - pthread_mutex_unlock(&mutex_trajets); + //usleep((rand() % 100 + 100)); + + pthread_mutex_lock(&mutex_trajets); + trajets_effectues++; + pthread_mutex_unlock(&mutex_trajets); + } return NULL; } - void *gestion_camion(void *arg) { -int velos_camion = 2; -while (1) { - pthread_mutex_lock(&mutex_trajets); - if (trajets_effectues >= HABITANTS) { + int velos_camion = 2; + while (1) { + pthread_mutex_lock(&mutex_trajets); + if (trajets_effectues >= HABITANTS * TRAJETS) { + pthread_mutex_unlock(&mutex_trajets); + printf("Camion arrête son travail, tous les trajets sont effectués.\n"); + break; + } pthread_mutex_unlock(&mutex_trajets); - break; // 🔹 Arrêt du camion lorsque tous les habitants ont terminé - } - pthread_mutex_unlock(&mutex_trajets); - for (int i = 0; i < SITES; i++) { - if (sites[i].velos_dispo > BORNES - 2 && velos_camion < CAMION_CAPACITE) { - while(sites[i].velos_dispo != BORNES - 2){ + + for (int i = 0; i < SITES; i++) { + pthread_mutex_lock(&sites[i].mutex); + if (sites[i].velos_dispo > BORNES - 2 && velos_camion < CAMION_CAPACITE && sites[i].velos_dispo > 1) { + while (sites[i].velos_dispo > BORNES - 2 && velos_camion < CAMION_CAPACITE && sites[i].velos_dispo > 1) { sem_wait(&sites[i].velos); + sem_post(&sites[i].bornes); sites[i].velos_dispo--; velos_camion++; - } - - printf("Camion prend un vélo ou 2 vélos au site %d\n", i); - } else if (sites[i].velos_dispo < 2 && velos_camion > 0) { - while(sites[i].velos_dispo != 2 && velos_camion != 0){ + } + printf("Camion prend des vélos au site %d (Vélos dans camion: %d)\n", i, velos_camion); + } else if (sites[i].velos_dispo < 2 && velos_camion > 0) { + while (sites[i].velos_dispo < 2 && velos_camion > 0) { + sem_wait(&sites[i].bornes); sem_post(&sites[i].velos); sites[i].velos_dispo++; velos_camion--; + } + printf("Camion dépose des vélos au site %d (Vélos dans camion: %d)\n", i, velos_camion); } - printf("Camion dépose un vélo au site %d\n", i); - } - usleep((rand() % 100 + 100)); - while(velos_camion > 2){ - velos_camion--; - velos_depot++; + pthread_mutex_unlock(&sites[i].mutex); + //usleep((rand() % 100 + 100)); } - while(velos_camion < 2 && velos_depot > 0){ - velos_camion++; - velos_depot--; + + if (velos_camion > 2) { + velos_depot += (velos_camion - 2); + velos_camion = 2; + printf("Camion vide les vélos au dépôt (Vélos en dépôt: %d)\n", velos_depot); } + + printf("Camion fait un tour, vélos restants: %d, vélos en dépôt: %d\n", velos_camion, velos_depot); + usleep((rand() % 100 + 199)); } + return NULL; } -return NULL; -} - -int main() { -pthread_t habitants[HABITANTS], camion; -sem_init(&depot, 0, 0); - -for (int i = 0; i < SITES; i++) { - sem_init(&sites[i].velos, 0, BORNES - 2); - sem_init(&sites[i].bornes, 0, 2); - sites[i].velos_dispo = BORNES - 2; -} - -for (int i = 0; i < HABITANTS; i++) { - int *id = malloc(sizeof(int)); - *id = i; - pthread_create(&habitants[i], NULL, habitant, id); -} -pthread_create(&camion, NULL, gestion_camion, NULL); -for (int i = 0; i < HABITANTS; i++) { - pthread_join(habitants[i], NULL); +int main(int argc, char *argv[]) { + if (argc != 5) { + fprintf(stderr, "Usage: %s <SITES> <HABITANTS> <TRAJETS> <BORNES>\n", argv[0]); + return 1; + } + + SITES = atoi(argv[1]); + HABITANTS = atoi(argv[2]); + TRAJETS = atoi(argv[3]); + BORNES = atoi(argv[4]); + + sites = malloc(SITES * sizeof(Site)); + + pthread_t habitants[HABITANTS], camion; + + for (int i = 0; i < SITES; i++) { + sem_init(&sites[i].velos, 0, BORNES - 2); + sem_init(&sites[i].bornes, 0, 2); + pthread_mutex_init(&sites[i].mutex, NULL); + sites[i].velos_dispo = BORNES - 2; + } + + for (int i = 0; i < HABITANTS; i++) { + int *id = malloc(sizeof(int)); + *id = i; + pthread_create(&habitants[i], NULL, habitant, id); + } + pthread_create(&camion, NULL, gestion_camion, NULL); + + for (int i = 0; i < HABITANTS; i++) { + pthread_join(habitants[i], NULL); + } + pthread_join(camion, NULL); + + int total_velos = velos_depot; + for (int i = 0; i < SITES; i++) { + total_velos += sites[i].velos_dispo; + printf("Site %d contains %d bykes\n", i, sites[i].velos_dispo); + } + total_velos += 2; + printf("Nombre total de vélos à la fin : %d (doit être %d)\n", total_velos, SITES * (BORNES - 2) + 2); + printf("Simulation terminée.\n"); + free(sites); + return 0; } - -pthread_cancel(camion); -printf("Simulation terminée.\n"); -return 0; -} \ No newline at end of file