Le projet dans son état est complet et fonctionnel avec quelques bugs a relever.
**Lancement du programme**
- via le makefile avec la cible `run` permettant de lancer le programme avec les arguments : S = 10, H = 100 , M = 10, N = 10 (modifiable avec la cible run ainsi)
```
make run ARGS="arg1 arg2 arg3 arg4"
```
- le lancement du programme se fait autrement via `./bykes arg1 arg2 arg3 arg4`
- arg1 -> nombre de sites (terminals)
- arg2 -> nombre de personnes a simuler (chacun dans un thread !)
- arg3 -> nombre de trajets par personnes
- arg4 -> nombre de bornes a vélos/bikes par sites/terminals
le programme est fonctionnel avec les arguments `10 100 10 10`, mais il peut se bloquer si l'on augmente le nombre de threads (notamment au dessus de 10000 threads avec par exemple les arguments ` ./bykes 100 10000 100 5000` ce qui devrait donné à la fin 499802 velos au total à la fin.)
## Fonctionnement de l'algorithme
l'algorithme est séparé en 3 librairies `civilian.h` (contenant l'algorithme des personnes), `Truck.h` (algo de la camionette) et enfin `city.h` qui est la structure principale avec les variables partagées dont les différents sites/terminals.
**city.h**
city contient les variables globales du programme :
```
#define USLEEP 1 //activate usleep() = 1 or no = 0
struct terminal{
int nb_bikesParked; //number of bikes parked in terminal
int nb_P_waiting; //number of persons waiting in terminal
sem_t *sem_FreeSlot; //semaphore of the free parking slots
sem_t *sem_BikeFree; //semaphore of the free bike
pthread_mutex_t *mutex; //mutex -> one for each terminal
};
struct city{
int npersons; //nb of persons in the city
int nSlots; //nb of slots for each terminal
int nTerminal; //nb of terminals in the city
int personsFinished; //nb of persons that finished
pthread_barrier_t b; //barrier to wait for every person
struct terminal *terminals; //all the terminals in the city
```
- d'abord le define USLEEP permettant d'activer les attentes usleep ou non
- la structure `city` qui contient toutes les variables partagée entre les threads, notamment personsFinished, et les terminals (les sites)
- chaque site contient un semaphore qui incrémente le BikeFree si qqun pose un vélo, puis décrémente le FreeSlots car une place de park sera prise.
- il contient également un mutex par terminal qui sera partagé aussi lorsque l'on accède aux variables partagées nb_bikesParked correspondant aux velos garés sur un terminal.
**civilian.h** + **Truck.h**
civilian.h contient une structure `person` qui contient l'essentiel de valeurs pour compter, mais aussi **afficher** les resultats sur le terminal.
```
struct person{
int num_thread;
int nb_travels;
int max_travels;
int i_terminals;
int nbTerminals;
int nslots;
};
```
Avec la structure city passée en variable globale dans la structure dans `civilian.c`.
Truck.h, das le principe fonctionne pareil, mais avec city passé directement en pointeur dans sa structure.
```
struct Truck{
int num_thread;
int n_bike;
int i_terminals;
int nbterminals;
int nslots;
int nbpersons;
struct city *city;
};
```
L'algorithme en lui même reprends le principe de producer consumer vu en cours :
- 2 types de sémaphores (1: velo de libre, 2: place de park de libre)
Les deux sont mis à jours ainsi :
1. qqun veut **prendre** un velo (est d'abord considéré en attente incrémenté dans des mutex), il va donc lancer un sem_wait en attente qu'un **velo** sois libre, pour ensuite le prendre et envoyer un sem_post indiquant qu'une **place** est libres
2. la personne fait son voyage jusqu'à j (j!=i) et se mets à nouveau en attente pour cette fois **poser** son velo avec sem_wait -> **place** de libre. au quel cas, il fait comme plus haut mais en inverse.
```
sem_wait(city_->terminals[j].sem_FreeSlot);
pthread_mutex_lock(city_->terminals[j].mutex);
... //critical section
pthread_mutex_unlock(city_->terminals[j].mutex);
sem_post(city_->terminals[j].sem_BikeFree);
```
3. autrement, c'est le camion qui va de la même manière s'occuper de placer ou de prendre un velo comme indiqué sur le tp.