diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f08278d85a0ff60e89c0d831ebbe8cec793e81fc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pdf \ No newline at end of file diff --git a/tp b/tp new file mode 100755 index 0000000000000000000000000000000000000000..71dc93f44ff8a634719c3edfc55ed4c9ad7a661c Binary files /dev/null and b/tp differ diff --git a/tp.c b/tp.c index 5c21837d6543d79818b8642e48cd87f8f8e73c53..9b9366aa3e4f4d89e26ae515dff86502f86107cb 100644 --- a/tp.c +++ b/tp.c @@ -3,6 +3,7 @@ #include <pthread.h> #include <semaphore.h> #include <unistd.h> +#include <time.h> #define CAMION_CAPACITE 4 @@ -10,6 +11,7 @@ typedef struct { sem_t velos; sem_t bornes; int velos_dispo; + int personnes_attente; pthread_mutex_t mutex; } Site; @@ -31,27 +33,39 @@ void *habitant(void *arg) { site_suivant = rand() % SITES; } while (site_suivant == site_actuel); + pthread_mutex_lock(&sites[site_actuel].mutex); + sites[site_actuel].personnes_attente++; + pthread_mutex_unlock(&sites[site_actuel].mutex); + 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--; + sites[site_actuel].personnes_attente--; 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)); + //usleep((rand() % 1000 + 1000)); + + pthread_mutex_lock(&sites[site_suivant].mutex); + sites[site_suivant].personnes_attente++; + pthread_mutex_unlock(&sites[site_suivant].mutex); - printf("(PUT) Habitant %d attend d'avoir accès à une borne du site %d\n", id, site_actuel); + printf("(PUT) Habitant %d attend d'avoir accès à une borne du site %d\n", id, site_suivant); sem_wait(&sites[site_suivant].bornes); + pthread_mutex_lock(&sites[site_suivant].mutex); sites[site_suivant].velos_dispo++; - sem_post(&sites[site_suivant].velos); + sites[site_suivant].personnes_attente--; pthread_mutex_unlock(&sites[site_suivant].mutex); + + sem_post(&sites[site_suivant].velos); printf("(PUT) Habitant %d dépose un vélo au site %d\n", id, site_suivant); + //usleep((rand() % 1000 + 1000)); site_actuel = site_suivant; - //usleep((rand() % 100 + 100)); pthread_mutex_lock(&mutex_trajets); trajets_effectues++; @@ -73,35 +87,66 @@ void *gestion_camion(void *arg) { 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) { + + // Fixed truck logic - ensure atomic operations with proper locking + if (sites[i].velos_dispo > BORNES - 2 && velos_camion < CAMION_CAPACITE) { + int aRetirer = sites[i].velos_dispo - (BORNES - 2); + if (aRetirer > CAMION_CAPACITE - velos_camion) + aRetirer = CAMION_CAPACITE - velos_camion; + + // Ensure we don't remove too many bikes + if (aRetirer > sites[i].velos_dispo-1) + aRetirer = sites[i].velos_dispo-1; + + for (int j = 0; j < aRetirer; j++) { sem_wait(&sites[i].velos); - sem_post(&sites[i].bornes); sites[i].velos_dispo--; velos_camion++; + sem_post(&sites[i].bornes); } + 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) { + } + else if (sites[i].velos_dispo < 2 && velos_camion > 0) { + int bikes_to_add = 2 - sites[i].velos_dispo; + if (bikes_to_add > velos_camion) + bikes_to_add = velos_camion; + + int available_slots = BORNES - sites[i].velos_dispo; + if (bikes_to_add > available_slots) + bikes_to_add = available_slots; + + for (int j = 0; j < bikes_to_add; j++) { sem_wait(&sites[i].bornes); - sem_post(&sites[i].velos); sites[i].velos_dispo++; velos_camion--; + sem_post(&sites[i].velos); } + printf("Camion dépose des vélos au site %d (Vélos dans camion: %d)\n", i, velos_camion); } + pthread_mutex_unlock(&sites[i].mutex); - //usleep((rand() % 100 + 100)); + usleep((rand() % 100 + 100)); } + pthread_mutex_lock(&mutex_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); + } else if (velos_camion < 2 && velos_depot > 0) { + int needed = 2 - velos_camion; + if (needed > velos_depot) + needed = velos_depot; + velos_depot -= needed; + velos_camion += needed; + printf("Camion prend des vélos du dépôt (Vélos en dépôt: %d)\n", velos_depot); } + pthread_mutex_unlock(&mutex_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)); + usleep((rand() % 100 + 100)); } return NULL; } @@ -117,6 +162,7 @@ int main(int argc, char *argv[]) { TRAJETS = atoi(argv[3]); BORNES = atoi(argv[4]); + srand(time(NULL)); sites = malloc(SITES * sizeof(Site)); pthread_t habitants[HABITANTS], camion; @@ -126,6 +172,7 @@ int main(int argc, char *argv[]) { sem_init(&sites[i].bornes, 0, 2); pthread_mutex_init(&sites[i].mutex, NULL); sites[i].velos_dispo = BORNES - 2; + sites[i].personnes_attente = 0; } for (int i = 0; i < HABITANTS; i++) { @@ -145,9 +192,17 @@ int main(int argc, char *argv[]) { total_velos += sites[i].velos_dispo; printf("Site %d contains %d bykes\n", i, sites[i].velos_dispo); } - total_velos += 2; + 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"); + + for (int i = 0; i < SITES; i++) { + sem_destroy(&sites[i].velos); + sem_destroy(&sites[i].bornes); + pthread_mutex_destroy(&sites[i].mutex); + } + pthread_mutex_destroy(&mutex_trajets); + pthread_mutex_destroy(&mutex_velos_depot); free(sites); return 0; -} +} \ No newline at end of file