From 70bb4fd94e446b2efae7d6b872ed0eb05328c4c9 Mon Sep 17 00:00:00 2001
From: Moncef STITI <moncef.stiti@etu.u-pec.fr>
Date: Thu, 5 Dec 2024 14:25:43 +0100
Subject: [PATCH] =?UTF-8?q?Am=C3=A9lioration?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Secured/README.md                           |   4 +-
 SecuredThread/secured_transaction_threads.c |   8 +-
 Unsecured/README.md                         |   4 +-
 Unsecured/unsecured_transaction.c           | 106 ++++++++++++++++++--
 4 files changed, 107 insertions(+), 15 deletions(-)

diff --git a/Secured/README.md b/Secured/README.md
index 920413e..ef33704 100644
--- a/Secured/README.md
+++ b/Secured/README.md
@@ -40,9 +40,9 @@ Exécutez le programme en spécifiant :
 
 Exemple :
 ```bash
-./secured_transaction 4 10
+./secured_transaction 30 50
 ```
-Ici, 4 processus seront lancés, chacun effectuant 10 transactions.
+Ici, 30 processus seront lancés, chacun effectuant 50 transactions.
 
 ---
 
diff --git a/SecuredThread/secured_transaction_threads.c b/SecuredThread/secured_transaction_threads.c
index ade36e4..f8c269f 100644
--- a/SecuredThread/secured_transaction_threads.c
+++ b/SecuredThread/secured_transaction_threads.c
@@ -18,11 +18,11 @@
 #define BLUE    "\033[34m"
 
 typedef struct {
-    int transactions;  // Nombre de transactions à effectuer
-    int account_count; // Nombre de comptes disponibles
-    int transactions_done; // Nombre de transactions effectuées
+    int transactions;        // Nombre de transactions à effectuer
+    int account_count;       // Nombre de comptes disponibles
+    int transactions_done;   // Nombre de transactions effectuées
     int transactions_failed; // Nombre de transactions annulées
-    int total_transfered; // Montant total transféré par le thread
+    int total_transfered;    // Montant total transféré par le thread
 } ThreadData;
 
 pthread_mutex_t file_mutex;  // Mutex pour protéger l'accès au fichier
diff --git a/Unsecured/README.md b/Unsecured/README.md
index 4a09d44..ae61124 100644
--- a/Unsecured/README.md
+++ b/Unsecured/README.md
@@ -37,9 +37,9 @@ Exécutez le programme en spécifiant :
 
 Exemple :
 ```bash
-./unsecured_transaction 4 10
+./unsecured_transaction 15 30
 ```
-Ici, 4 processus seront lancés, chacun effectuant 10 transactions.
+Ici, 15 processus seront lancés, chacun effectuant 30 transactions.
 
 ---
 
diff --git a/Unsecured/unsecured_transaction.c b/Unsecured/unsecured_transaction.c
index c22fc51..7b557e4 100644
--- a/Unsecured/unsecured_transaction.c
+++ b/Unsecured/unsecured_transaction.c
@@ -17,36 +17,85 @@
 #define PINK  "\033[35m"
 #define BLUE    "\033[34m"
 
-// Fonction pour lire un compte dans le fichier avec verrouillage
+/**
+ * @brief Écrit les informations d'un compte dans un fichier sans verrouillage.
+ * 
+ * Cette fonction écrit un compte spécifié par son index dans le fichier
+ * spécifié par le descripteur de fichier. Avant d'écrire, elle formate les
+ * données du compte (nom et solde) pour les rendre compatibles avec la taille
+ * d'un enregistrement.
+ *
+ * @param fd Le descripteur de fichier du fichier contenant les comptes.
+ * @param index L'index du compte à écrire (en termes de position dans le fichier).
+ * @param name Le nom du compte à écrire.
+ * @param balance Le solde du compte à écrire.
+ * 
+ */
 void read_account(int fd, int index, char *name, int *balance) {
     char buffer[ACCOUNT_SIZE];
 
+    // Se positionner à l'index du compte dans le fichier
     lseek(fd, index * ACCOUNT_SIZE, SEEK_SET);
+
+    // Lire l'enregistrement du compte
     read(fd, buffer, ACCOUNT_SIZE);
+
+    // Extraire le nom et le solde du compte
     sscanf(buffer, "%7s %d", name, balance);
 }
 
-// Fonction pour écrire un compte dans le fichier avec verrouillage
+
+/**
+ * @brief Écrit les informations d'un compte dans un fichier sans verrouillage.
+ * 
+ * Cette fonction écrit un compte spécifié par son index dans le fichier
+ * spécifié par le descripteur de fichier. Avant d'écrire, elle formate les
+ * données du compte (nom et solde) pour les rendre compatibles avec la taille
+ * d'un enregistrement.
+ *
+ * @param fd Le descripteur de fichier du fichier contenant les comptes.
+ * @param index L'index du compte à écrire (en termes de position dans le fichier).
+ * @param name Le nom du compte à écrire.
+ * @param balance Le solde du compte à écrire.
+ * 
+ */
 void write_account(int fd, int index, const char *name, int balance) {
     char buffer[ACCOUNT_SIZE];
 
-    // Formater la chaîne avec un nom de 10 caractères et un solde de 5 caractères, espace rempli si nécessaire
+    // Formater la chaîne avec un nom et un solde
     snprintf(buffer, ACCOUNT_SIZE, "%-7s%8d", name, balance);
 
     // S'assurer que le buffer est exactement de taille ACCOUNT_SIZE
     for (int i = strlen(buffer); i < ACCOUNT_SIZE - 1; i++) {
         buffer[i] = ' ';
     }
-    buffer[ACCOUNT_SIZE - 1] = '\n';  // Assurez-vous que la ligne est terminée correctement
+    buffer[ACCOUNT_SIZE - 1] = '\n';  // S'assurer que la ligne est terminée correctement
 
     lseek(fd, index * ACCOUNT_SIZE, SEEK_SET);
     write(fd, buffer, ACCOUNT_SIZE);
 }
 
-// Fonction pour effectuer une transaction avec verrouillage
+/**
+ * @brief Effectue une transaction aléatoire entre deux comptes sans verrouillage.
+ * 
+ * Cette fonction simule une transaction entre deux comptes distincts sélectionnés
+ * aléatoirement. Le montant transféré est calculé aléatoirement et ne dépasse pas
+ * 20% du solde du compte source.
+ * 
+ * @param fd Le descripteur de fichier du fichier contenant les comptes.
+ * @param account_count Le nombre total de comptes dans le fichier.
+ * 
+ * @note Les comptes source et destination sont choisis de manière aléatoire, 
+ * mais un compte ne peut pas transférer à lui-même.
+ * @note La transaction est annulée si le solde du compte source est insuffisant
+ * pour effectuer un transfert minimal.
+ * 
+ */
 void perform_transaction(int fd, int account_count) {
     int from_idx = rand() % account_count;
     int to_idx = rand() % account_count;
+
+    // Sélectionner un autre compte si source et destination sont identiques
     while (from_idx == to_idx) {
         to_idx = rand() % account_count;
     }
@@ -77,7 +126,26 @@ void perform_transaction(int fd, int account_count) {
     }
 }
 
-// Fonction pour un processus de transactions
+/**
+ * @brief Effectue un ensemble de transactions dans un processus.
+ * 
+ * Cette fonction ouvre le fichier contenant les comptes en mode lecture/écriture
+ * et effectue un nombre donné de transactions aléatoires. Chaque transaction est
+ * réalisée en appelant la fonction `perform_transaction`. Une temporisation aléatoire
+ * est introduite entre les transactions pour simuler un comportement réaliste.
+ * 
+ * @param transactions Le nombre de transactions à effectuer.
+ * @param account_count Le nombre total de comptes dans le fichier.
+ * 
+ * @note La fonction ouvre le fichier spécifié par `FILENAME` en mode lecture/écriture.
+ * Elle s'assure de le fermer correctement à la fin.
+ * 
+ * @warning Si l'ouverture du fichier échoue, la fonction interrompt le programme
+ * avec un appel à `exit(1)`.
+ * 
+ * @details
+ * - La temporisation introduite par `usleep` (avec une durée aléatoire) contribue à la simulation d'un trafic réseau ou de retards dans les transactions.
+ */
 void process_transactions(int transactions, int account_count) {
     int fd = open(FILENAME, O_RDWR);
     if (fd < 0) {
@@ -87,12 +155,29 @@ void process_transactions(int transactions, int account_count) {
 
     for (int i = 0; i < transactions; i++) {
         perform_transaction(fd, account_count);
-        //usleep(rand() % 100000); // Temporisation aléatoire
+        usleep(rand() % 100000); // Temporisation aléatoire
     }
 
     close(fd);
 }
 
+/**
+ * @brief Calcule le solde total de tous les comptes dans le fichier.
+ * 
+ * Cette fonction parcourt tous les comptes stockés dans le fichier spécifié
+ * par `FILENAME`, en lisant leurs soldes et en les additionnant pour produire
+ * un solde total. Elle ouvre le fichier en mode lecture seule, le parcourt
+ * compte par compte, puis le ferme avant de retourner le résultat.
+ * 
+ * @return Le solde total de tous les comptes, ou -1 en cas d'erreur
+ * (par exemple, si l'ouverture du fichier échoue).
+ * 
+ * @note La taille de chaque compte est définie par la constante `ACCOUNT_SIZE`.
+ * 
+ * @warning Cette fonction ne valide pas les données des comptes lues depuis le fichier.
+ * Elle suppose que les données sont correctement formatées.
+ * 
+ */
 int calculate_total_balance() {
     int fd = open(FILENAME, O_RDONLY);
     if (fd < 0) {
@@ -116,15 +201,21 @@ int calculate_total_balance() {
     return total_balance;
 }
 
+// Fonction principale
 int main(int argc, char *argv[]) {
+    // Vérifier que deux arguments sont passés en paramètre
     if (argc != 3) {
         fprintf(stderr, "Usage: %s <number_of_processes> <transactions_per_process>\n", argv[0]);
         return 1;
     }
 
+     // Extraire le nombre de processus et le nombre de transactions par processus
     int num_processes = atoi(argv[1]);
     int transactions_per_process = atoi(argv[2]);
 
+    // Initialiser une graine aléatoire basée sur l'ID de processus et l'heure actuelle
+    // On aurait aussi pu utiliser la fonction rand() directement, mais rand_r() est plus sûr
+    // Car il permet d'éviter les interférences entre les processus
     unsigned int seed = getpid() ^ time(NULL);
     int random_value = rand_r(&seed);
 
@@ -168,6 +259,7 @@ int main(int argc, char *argv[]) {
     }
     printf("Solde total final : %d€\n", final_balance);
 
+    // Vérifier que le solde initial et le solde final sont identiques
     if (initial_balance != final_balance) {
         printf("Le solde final est différent du solde initial...\n");
     }