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

Projet_M2 - format inginious

parent e39d35fb
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Pipeline #5557 en échec
all : fact
fact : run.o test.o
gcc -g -std=c99 -o fact run.o test.o -lpthread -I${HOME}/local/include -lcunit -L${HOME}/local/lib
run.o : run.c
gcc -g -std=c99 -o run.o -c run.c -W -Wall -lpthread
test.o : test.c run.h
gcc -g -std=c99 -o test.o -c test.c -I${HOME}/local/include -W -Wall -lcunit -lpthread
clean :
rm -rf fact *.o *.xml "actual_output.txt"
test : fact
./fact Test
cpp : run.c
cppcheck --enable=all run.c
val : fact
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./fact Test_files/short_input.txt output.txt
# lepl1503-2020-groupe-M2
Pour compiler le programme : make fact
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
Pour compiler et effectuer une analyse avec "Valgrind" : make val
Pour effectuer une analyse avec "cppcheck" : make cpp
Pour nettoyer les fichiers auxiliaires générés et l'exécutable : make clean
666343 7487 89
463698 277 31 3 2
1021406 7193 71 2
506156 18077 7 2
913231 1361 61 11
268205 97 79 7 5
982865 15121 13 5
917451 101939 3
499176 2311 3 2
529973
746782 5573 67 2
276324 23027 3 2
435465 9677 5 3
352649 32059 11
104121 503 23 3
981518 113 101 43 2
413102 206551 2
880413 283 61 17 3
676364 13007 13 2
804603 4003 67 3
1012028 2239 113 2
364381 787 463
780260 3001 13 5 2
907169
142193
408465 313 29 5 3
266175 13 7 5 3
171413 15583 11
518652 14407 3 2
770297 293 239 11
134273 191 37 19
638327
826830 9187 5 3 2
220605 191 11 7 5 3
162237 1319 41 3
53202 8867 3 2
494421 5683 29 3
309475 12379 5
361113 120371 3
1033840 12923 5 2
319499
981506 1367 359 2
404743 10939 37
897560 1181 19 5 2
1023027 3187 107 3
354480 211 7 5 3 2
793492 1667 17 7 2
102802 1049 7 2
843491 6971 11
983760 4099 5 3 2
404152 1031 7 2
283682 881 23 7 2
526652 2687 7 2
1018 509 2
324508 2617 31 2
103308 8609 3 2
9422 673 7 2
793590 3779 7 5 3 2
241316 61 43 23 2
132914 66457 2
978150 6521 5 3 2
725819 38201 19
828636 347 199 3 2
224489 7741 29
431210 107 31 13 5 2
705190 727 97 5 2
470751 4241 37 3
182145 12143 5 3
728190 31 29 5 3 2
3574 1787 2
813793 1933 421
17035 3407 5
795384 11047 3 2
534134 5039 53 2
498463 71209 7
385529 197 103 19
624262 683 457 2
697671 89 67 13 3
613191 204397 3
866262 409 353 3 2
58631
290417 3499 83
901545 60103 5 3
86993
607222 3943 11 7 2
437288 1163 47 2
122029
840703
647460 109 11 5 3 2
42875 7 5
135229 499 271
1033268 258317 2
361034 1861 97 2
916343 39841 23
739080 2053 5 3 2
975089
82667 6359 13
670049
640632 26693 3 2
950453 163 17 7
666343
463698
1021406
506156
913231
268205
982865
917451
499176
529973
746782
276324
435465
352649
104121
981518
413102
880413
676364
804603
1012028
364381
780260
907169
142193
408465
266175
171413
518652
770297
134273
638327
826830
220605
162237
53202
494421
309475
361113
1033840
319499
981506
404743
897560
1023027
354480
793492
102802
843491
983760
404152
283682
526652
1018
324508
103308
9422
793590
241316
132914
978150
725819
828636
224489
431210
705190
470751
182145
728190
3574
813793
17035
795384
534134
498463
385529
624262
697671
613191
866262
58631
290417
901545
86993
607222
437288
122029
840703
647460
42875
135229
1033268
361034
916343
739080
975089
82667
670049
640632
950453
981518 113 101 43 2
981518
#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>
int N;
//travailler avec des linkendList
typedef struct node{
unsigned long long value;
struct node *next;
}node_t;
typedef struct queue{
struct node *tail;
int size;
int final;
}queue_t;
struct buffer_rc{
char *tab[8];
int size;
int len;
int head;
int tail;
int stop;
FILE *file1;
};
struct buffer_cw
{
queue_t *tab[8];
int size;
int len;
int head;
int tail;
int stop;
FILE *file2;
};
struct buffer_rccw{
struct buffer_rc *struct1;
struct buffer_cw *struct2;
};
/* sémaphore est une structure de donné qui contient :
*un entier qui stocke la valeur, positive ou nulle du sémaphore.
*une queue qui contient les pointeurs vers les threads
*/
pthread_mutex_t mutex1;
sem_t empty1;
sem_t full1;
pthread_mutex_t mutex2;
sem_t empty2;
sem_t full2;
void put_in_buffer_1(char *c, struct buffer_rc *ptr){ //ajouter un element dans le buffer 1
ptr->tab[ptr->head] = malloc(sizeof(c)); // on stoxke de espace
//ptr->tab[ptr->head] = c;
strcpy(ptr->tab[ptr->head],c); //copie
ptr->len++; // augmente l'espace occupé par le buffer
ptr->head = (ptr->head + 1)%ptr->size; //chaque fois qu'un élément est ajouté,
//on augmente le pointeur de 1 mais l'espace du buffer est de 8 donc faire un modulo
}
char *get_from_buffer_1(struct buffer_rc *ptr){ // chercher dans le buffer 1
char *result;
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->tail = (ptr->tail + 1)%ptr->size;
return result;
}
void put_in_buffer_2(struct queue *ptr, struct buffer_cw *buf){ //ajouter un element dans le buffer 2
buf->tab[buf->head] = ptr;
buf->len++; //augmenté l'espace occupé par 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->len--; //diminue l'espace occupé par le buffer
buf->tail = (buf->tail + 1)%buf->size;
return result;
}
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
}
int is_prime(unsigned long long number) { // Vérifie si number est un nombre premier. Return 1 si il est premier, 0 sinon
if (number != 2) {
if (number % 2 == 0) {
return 0 ;
}
}
for (unsigned long long i = 3 ; i <= (number/2); i = i + 2) { //regarde les differents nombres pouvant etre diviser number
if (is_div(number,i) != 0) { // si i peut diviser number
return 0 ; //renvoi 0 => FAUX
}
}
return 1 ; //sinon => VRAI
}
void enqueue(queue_t* q, unsigned long long val){
struct node *ptr;
ptr = malloc(sizeof(node_t));
if (ptr == NULL){
free(ptr);
return;}
ptr -> value = val;
ptr -> next = malloc(sizeof(node_t));
if (q->size == 0)
{
*q->tail = *ptr;
*ptr->next = *ptr;
}
else{
*ptr->next = *q->tail->next;
*q->tail->next = *ptr;
}
q->size++;
//return q;
//free(ptr->next);
free(ptr);
}
queue_t* prime_divs(unsigned long long number){
struct queue new_queue;
new_queue.size = 0;
new_queue.final = 0;
new_queue.tail = malloc(sizeof(node_t));
if(new_queue.tail==NULL){return NULL;}
struct queue *ptr;
ptr = malloc(sizeof(queue_t));
if (ptr == NULL){
free(new_queue.tail);
free(ptr);
return NULL;}
*ptr = new_queue;
for (unsigned long long i = 2; i <= number/2; i++){
if (is_div(number, i) && is_prime(i) == 1){
enqueue(ptr,i);
}
}
enqueue(ptr,number);
return ptr;
}
void *writing(void *param){
struct buffer_cw *param1 = (struct buffer_cw *) param;
int stop = 0;
while(param1->stop == 0){
sem_wait(&full2);
pthread_mutex_lock(&mutex2);
queue_t *pr_divs = get_from_buffer_2(param);
pthread_mutex_unlock(&mutex2);
sem_post(&empty2);
if (pr_divs->final == 1)
{
//printf("final : %d\n",pr_divs->final);
if (stop == N-1){
free(pr_divs);
return NULL;
}
free(pr_divs);
stop++;
}
else{
FILE *file2 = param1->file2;
struct node *current;
current = malloc(sizeof(node_t));
if (current == NULL){return NULL;}
*current = *pr_divs->tail;
current = current->next;
fprintf(file2,"%llu",current->value);
current = current->next;
for (int i = 1; i < pr_divs->size; i++)
{
fprintf(file2," %llu",current->value);
current = current->next;
}
fputc('\n',file2);
free(current);
}
}
return NULL;
}
void *calculating(void *param){
struct buffer_rccw *param1 = (struct buffer_rccw *) param;
struct buffer_rc *buffer_1 = param1->struct1;
struct buffer_cw *buffer_2 = param1->struct2;
while(buffer_1->stop == 0){
sem_wait(&full1);
pthread_mutex_lock(&mutex1);
char *chaine = get_from_buffer_1(buffer_1);
pthread_mutex_unlock(&mutex1);
sem_post(&empty1);
if (strcmp("stop",chaine) == 0)
{
struct queue *final;
final = malloc(sizeof(queue_t));
if (final == NULL){return NULL;}
final->final = 1;
sem_wait(&empty2);
pthread_mutex_lock(&mutex2);
put_in_buffer_2(final,buffer_2);
pthread_mutex_unlock(&mutex2);
sem_post(&full2);
return NULL;
}
struct queue *pr_divs;
pr_divs = malloc(sizeof(queue_t));
if (pr_divs == NULL){return NULL;}
pr_divs = prime_divs(strtoll(chaine,NULL,0));
sem_wait(&empty2);
pthread_mutex_lock(&mutex2);
put_in_buffer_2(pr_divs,buffer_2);
pthread_mutex_unlock(&mutex2);
sem_post(&full2);
free(pr_divs->tail);
free(pr_divs);
}
return NULL;
}
void *reading (void *param){
struct buffer_rc *param1= (struct buffer_rc *) param;
char chaine[30];
FILE *input;
//input = malloc(sizeof(FILE*));
input = param1->file1;
while (fgets(chaine,30,input) != NULL){
sem_wait(&empty1);
pthread_mutex_lock(&mutex1);
put_in_buffer_1(chaine,param1); //put each line in the buffer #1
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
pthread_mutex_unlock(&mutex1);
sem_post(&full1);
}
return NULL;
}
void sem_1_initializer(struct buffer_rc *buf){
pthread_mutex_init(&mutex1,NULL);
sem_init(&empty1,0,buf->size);
sem_init(&full1,0,0);
}
void sem_2_initializer (struct buffer_cw *buf){
pthread_mutex_init(&mutex2,NULL);
sem_init(&empty2,0,buf->size);
sem_init(&full2,0,0);
}
struct buffer_rc * buff_init_1(FILE *file1){
struct buffer_rc *ptr1;
ptr1 = malloc(sizeof(struct buffer_rc));
if (ptr1 == NULL){
free(ptr1);
return NULL;}
ptr1->size = 2*N;
ptr1->len = 0;
ptr1->head = 0;
ptr1->tail = 0;
ptr1->stop = 0;
ptr1->file1 = file1;
return ptr1;
}
struct buffer_cw * buff_init_2(FILE *file2){
struct buffer_cw *ptr2;
ptr2 = malloc(sizeof(struct buffer_cw));
if (ptr2 == NULL){
return NULL;}
ptr2->size = 2*N;
ptr2->len = 0;
ptr2->head = 0;
ptr2->tail = 0;
ptr2->stop = 0;
ptr2->file2 = file2;
return ptr2;
}
struct buffer_rccw *buff_init_12(struct buffer_rc *ptr1,struct buffer_cw *ptr2){
struct buffer_rccw buffer_12;
buffer_12.struct1 = ptr1;
buffer_12.struct2 = ptr2;
struct buffer_rccw *ptr3;
ptr3 = malloc(sizeof(struct buffer_rccw));
if (ptr3 == NULL){return NULL;}
*ptr3 = buffer_12;
return ptr3;
}
void thread_create_join(struct buffer_rc *ptr1,struct buffer_cw *ptr2,struct buffer_rccw *ptr3){
pthread_t reader;
pthread_t calculators[N];
pthread_t writer;
pthread_create(&reader,NULL,&reading,ptr1);
for (int i = 0; i < N; i++)
{
pthread_create(&calculators[i],NULL,&calculating,ptr3);
}
pthread_create(&writer,NULL,&writing,ptr2);
pthread_join(reader,NULL);
for (int i = 0; i < N; i++)
{
pthread_join(calculators[i],NULL);
}
pthread_join(writer,NULL);
}
int run (char *input,char *output, int n_threads){
N = n_threads;
FILE *file1 = NULL;
FILE *file2 = NULL;
file1 = fopen(input,"r");
if (file1 == NULL){
printf("Sorry, file %s doesn't exist ): \n",input);
return -1;}
file2 = fopen(output,"w+");
if (file2 == NULL){
fclose(file1);
return -1;
}
struct buffer_rc *ptr1 = buff_init_1(file1);
struct buffer_cw *ptr2 = buff_init_2(file2);
struct buffer_rccw *ptr3 = buff_init_12(ptr1,ptr2);
sem_1_initializer(ptr1);
sem_2_initializer(ptr2);
thread_create_join(ptr1,ptr2,ptr3);
fclose(file1);
fclose(file2);
free(ptr1);
free(ptr2);
free(ptr3);
return 1;
}
/* int main() {
int err = run("input.txt", "actual_output.txt");
return err;
} */
#ifndef RUN
#define RUN
#include <pthread.h>
#include <semaphore.h>
typedef struct node{
unsigned long long value;
struct node *next;
}node_t;
typedef struct queue{
struct node *tail;
int size;
}queue_t;
struct buffer_rc{
char *tab[8];
int size;
int len;
int head;
int tail;
};
struct buffer_cw
{
queue_t *tab[8];
int size;
int len;
int head;
int tail;
};
struct buffer_rccw{
struct buffer_rc *struct1;
struct buffer_cw *struct2;
};
pthread_mutex_t mutex1;
sem_t empty1;
sem_t full1;
pthread_mutex_t mutex2;
sem_t empty2;
sem_t full2;
void put_in_buffer_1(char *c);
char *get_from_buffer_1(void);
void put_in_buffer_2(struct queue *ptr);
queue_t *get_from_buffer_2(void);
int is_div(unsigned long long number, long i);
int is_prime(unsigned long long number);
void enqueue(queue_t* q, unsigned long long val);
queue_t* prime_divs(unsigned long long number);
void *reading (void *param);
void *calculating(void *param);
void *writing(void *param);
void sem_1_initializer(struct buffer_rc *buf);
void sem_2_initializer (struct buffer_cw *buf);
struct buffer_rc * buff_init_1(FILE *file1);
struct buffer_cw * buff_init_2(FILE *file2);
struct buffer_rccw *buff_init_12(struct buffer_rc *ptr1,struct buffer_cw *ptr2);
void thread_create_join(struct buffer_rc *ptr1,struct buffer_cw *ptr2,struct buffer_rccw *ptr3);
int run (char *input,char *output,int n_threads);
#endif
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include "run.h"
#include <CUnit/CUnit.h>
#include <CUnit/TestRun.h>
#include <CUnit/CUError.h>
#include <CUnit/Basic.h>
#include <CUnit/Automated.h>
void test_is_div(void){
CU_ASSERT_TRUE(is_div(14,7));
}
void test_is_prime(void){
CU_ASSERT_TRUE(is_prime(13));
}
void test_is_not_prime(void){
CU_ASSERT_FALSE(is_prime(14));
}
void empty_file_test(void){
FILE *file1 = NULL;
int err = run("Test_files/empty_input.txt","actual_output.txt",4);
if (err == -1){
CU_FAIL("method run failed");
return;
}
file1 = fopen("actual_output.txt","r");
if (file1 == NULL){
CU_FAIL("actual_output opening fail");
return;
}
char chaine1[20];
CU_ASSERT_EQUAL(fgets(chaine1,20,file1),NULL);
fclose(file1);
}
void short_file_test(void){
FILE *file1 = NULL;
FILE *file2 = NULL;
file1 = fopen("Test_files/short_expected_output.txt","r");
if (file1 == NULL){
CU_FAIL("short_expected_output opening fail");
return;
}
int err = run("Test_files/short_input.txt","actual_output.txt",4);
if (err == -1){
CU_FAIL("method run failed");
return;
}
file2 = fopen("actual_output.txt","r");
if (file2 == NULL){
CU_FAIL("actual_output opening fail");
return;
}
char chaine1[50];
char chaine2[50];
while (fgets(chaine1,50,file1) != NULL && fgets(chaine2,50,file2) != NULL)
{
//printf("%s\n",chaine1);
//printf("%s\n",chaine2);
CU_ASSERT_STRING_EQUAL(chaine1,chaine2);
}
fclose(file1);
fclose(file2);
}
void file_test(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",4);
end = clock();
time = (double) (end - start) / CLOCKS_PER_SEC;
printf("Temps = %.2f secondes \n",time);
if (err == -1){
CU_FAIL("method run failed");
return;
}
file2 = fopen("actual_output.txt","r");
if (file2 == NULL){
CU_FAIL("actual_output opening fail");
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);
fclose(file2);
}
int setup(void){
return 0;
}
int teardown(void)
{
return 0;
}
int main(int argc, char *argv[]){
if (argc == 2 && strcmp(argv[1],"Test")==0){
if (CUE_SUCCESS != CU_initialize_registry())
{
return CU_get_error();
}
CU_pSuite pSuite = NULL;
pSuite = CU_add_suite("ma_suite",setup,teardown);
if (NULL == pSuite)
{
CU_cleanup_registry();
return CU_get_error();
}
if (NULL == CU_add_test(pSuite,"test_is_div",test_is_div) ||
NULL == CU_add_test(pSuite, "test_is_prime",test_is_prime) ||
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))
{
CU_cleanup_registry();
return CU_get_error();
}
CU_basic_run_tests();
//CU_automated_run_tests();
CU_basic_show_failures(CU_get_failure_list());
}
else
{
if (argc == 5 && strcmp("-N",argv[1])==0){
return run(argv[3],argv[4],atoi(argv[2]));
}
else
{
if (argc == 3){
return run(argv[1],argv[2],4);
}
else{
printf("Invalid type of number of arguments, please try again with the right format\n");
}
}
return 1;
}
}
\ No newline at end of file
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