Skip to content
Extraits de code Groupes Projets
Valider 615d9c1f rédigé par Laurent Paucot's avatar Laurent Paucot
Parcourir les fichiers

readme et tests + complets

parent 8e791418
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Pipeline #6091 réussi
......@@ -2,7 +2,7 @@
Pour compiler le programme : make fact
Pour exécuter le fichier exécutable fact : ./fact [-N nombre_de_threads] input output
Pour exécuter le fichier exécutable "fact" : ./fact [-N nombre_de_threads] input output
Pour compiler et tester (suite de tests unitaires) le programme : make test
......@@ -12,3 +12,42 @@ Pour effectuer une analyse avec "cppcheck" : make cpp
Pour nettoyer les fichiers auxiliaires générés et l'exécutable : make clean
Architecture du programme:
Le travail est décomposé en 3 sections coordonnées via un double problème du producteur-consommateur :
-> 1 thread s'occupe de:
§ lire le fichier input
§ stocker chacune des lignes sous forme de chaine de charactère dans un 1er tableau
-> N threads s'occupent de :
§ récupérer les chaines de caractères dans le premier tableau
§ les convertir en 'unsigned long long' et calculer leur liste de diviseurs premiers
§ Stocker ces listes dans un 2e tableau
-> 1 thread s'occupe de :
§ récupérer les listes de diviseurs dans le 2e tableau
§ Retranscrire dans le bon format le nombre à factoriser et ses diviseurs premiers dans le fichier output
Note :
§ Les accès aux tableaux sont coordonnés par des mutex (1 par tableau) et des sémaphores
§ Les diviseurs premiers d'un même nombre sont stockés dans une circular linked list
Architecture des tests :
6 tests sont réalisés afin de tester:
§ La fonction is_div
§ La fonction is_prime (2 tests)
§ Le fonctionnement complet pour un fichier vide (N = 4)
§ Le fonctionnement complet pour un fichier d'une ligne : check du format et des diviseurs (N = 4)
§ Le fonctionnement complet pour un fichier de 100 lignes : check du nombre de lignes (réalisé avec N = 4 puis N = 1)
# lepl1503-2020-groupe-M2
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <pthread.h>
#include <semaphore.h>
......@@ -78,7 +75,7 @@ char *get_from_buffer_1(struct buffer_rc *ptr){ // chercher dans le buffer 1
result = ptr->tab[ptr->tail]; // donne un valeur a result
//free(ptr->tab[ptr->tail]);
ptr->tab[ptr->tail] = NULL;
ptr->len--; //diminue l'espace occupé par le buffer
ptr->len--; //diminue l'espace occupé dans le buffer
ptr->tail = (ptr->tail + 1)%ptr->size;
return result;
......@@ -87,12 +84,12 @@ char *get_from_buffer_1(struct buffer_rc *ptr){ // chercher dans le buffer 1
void put_in_buffer_2(struct queue *ptr, struct buffer_cw *buf){ //ajouter un element dans le buffer 2
buf->tab[buf->head] = malloc(sizeof(*ptr));
buf->tab[buf->head] = ptr;
buf->len++; //augmenté l'espace occupé par le buffer
buf->len++; //augmente l'espace occupé dans le buffer
buf->head = (buf->head + 1)%buf->size;
}
queue_t *get_from_buffer_2(struct buffer_cw *buf){ // trouver un element
//printf("%d\n",buf->len);
struct queue *result;
result = buf->tab[buf->tail]; //donne une valeur a result
buf->tab[buf->tail] = NULL;
......@@ -104,7 +101,7 @@ queue_t *get_from_buffer_2(struct buffer_cw *buf){ // trouver un element
int is_div(unsigned long long number, unsigned long long i) { // Vérifie si i est un diviseur de number.
return (number % i == 0) ; // revoi 0 si le nombre n'est pas divisible par i et 1 si il est divisible
return (number % i == 0) ; // renvoie 0 si le nombre n'est pas divisible par i et 1 si il est divisible
}
......@@ -146,7 +143,7 @@ void enqueue(queue_t* q, unsigned long long val){
*q->tail->next = *ptr;
}
q->size++;
//return q;
//free(ptr->next);
free(ptr);
......@@ -195,7 +192,7 @@ void *writing(void *param){
if (pr_divs->final == 1)
{
//printf("final : %d\n",pr_divs->final);
if (stop == N-1){
for (int i = 0; i < param1->size; i++)
{
......@@ -281,11 +278,6 @@ void *calculating(void *param){
pthread_mutex_unlock(&mutex2);
sem_post(&full2);
//free(pr_divs->tail);
//free(pr_divs);
}
return NULL;
......@@ -298,7 +290,6 @@ void *reading (void *param){
char chaine[30];
FILE *input;
//input = malloc(sizeof(FILE*));
input = param1->file1;
while (fgets(chaine,30,input) != NULL){
......@@ -311,14 +302,13 @@ void *reading (void *param){
pthread_mutex_unlock(&mutex1);
sem_post(&full1);
}
//param1->stop = 1;
for (int i = 0; i < N; i++)
{
sem_wait(&empty1);
pthread_mutex_lock(&mutex1);
put_in_buffer_1("stop\0",param1); //put each line in the buffer #1
put_in_buffer_1("stop\0",param1); //put each stop line in the buffer #1
pthread_mutex_unlock(&mutex1);
sem_post(&full1);
......@@ -449,9 +439,3 @@ int run (char *input,char *output, int n_threads){
return EXIT_SUCCESS;
}
/* int main() {
int err = run("input.txt", "actual_output.txt");
return err;
} */
......@@ -80,7 +80,7 @@ void short_file_test(void){
fclose(file2);
}
void file_test(void){
void file_test_N_4(void){
FILE *file1 = NULL;
FILE *file2 = NULL;
......@@ -93,18 +93,65 @@ void file_test(void){
clock_t start, end;
double time;
start = clock();
printf("check1\n");
int err = run("Test_files/input.txt","actual_output.txt",4);
end = clock();
time = (double) (end - start) / CLOCKS_PER_SEC;
printf("Temps = %.2f secondes \n",time);
printf("Temps pour 4 threads de calculs = %.2f secondes \n",time);
if (err == -1){
CU_FAIL("method run failed");
fclose(file1);
return;
}
printf("checkfinal\n");
file2 = fopen("actual_output.txt","r");
if (file2 == NULL){
CU_FAIL("actual_output opening fail");
fclose(file1);
return;
}
char chaine2[50];
int n = 0;
while (fgets(chaine2,50,file2) != NULL)
{
n++;
}
CU_ASSERT_EQUAL(n,100);
fclose(file1);
fclose(file2);
}
void file_test_N_1(void){
FILE *file1 = NULL;
FILE *file2 = NULL;
file1 = fopen("Test_files/expected_output.txt","r");
if (file1 == NULL){
CU_FAIL("expected_output opening fail");
return;
}
clock_t start, end;
double time;
start = clock();
int err = run("Test_files/input.txt","actual_output.txt",1);
end = clock();
time = (double) (end - start) / CLOCKS_PER_SEC;
printf("Temps pour 1 thread de calcul = %.2f secondes \n",time);
if (err == -1){
CU_FAIL("method run failed");
fclose(file1);
return;
}
file2 = fopen("actual_output.txt","r");
if (file2 == NULL){
CU_FAIL("actual_output opening fail");
......@@ -112,19 +159,14 @@ void file_test(void){
return;
}
//char chaine1[50];
char chaine2[50];
int n = 0;
while (fgets(chaine2,50,file2) != NULL)
{
//printf("%s\n",chaine1);
//printf("%s\n",chaine2);
//CU_ASSERT_STRING_EQUAL(chaine1,chaine2);
n++;
}
//printf("%d",n);
CU_ASSERT_EQUAL(n,100);
fclose(file1);
......@@ -166,7 +208,8 @@ int main(int argc, char *argv[]){
NULL == CU_add_test(pSuite, "test_is_not_prime",test_is_not_prime) ||
NULL == CU_add_test(pSuite,"empty_file_test",empty_file_test) ||
NULL == CU_add_test(pSuite,"short_file_test",short_file_test) ||
NULL == CU_add_test(pSuite,"file_test",file_test))
NULL == CU_add_test(pSuite,"file_test : N = 4",file_test_N_4) ||
NULL == CU_add_test(pSuite,"file_test N = 1",file_test_N_1))
{
CU_cleanup_registry();
return CU_get_error();
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter