Skip to content
Extraits de code Groupes Projets
Valider 2e0d368a rédigé par Corentin Lengelé's avatar Corentin Lengelé
Parcourir les fichiers

Code refractor

parent a84b1551
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
## Description ## Description
This repository git is the project for the course LEPL11503 made by the team C1 composed by : This repository git is the project for the course LEPL11503 made by the team C1 composed by :
* Hugo Clercq 0703 1700 * Hugo Clercq 0703-17-00
* Maxime Jacques de Dixmude Slavic 6205 1500 * Maxime Jacques de Dixmude Slavic 6205-15-00
* Arnaud Lahousse 5629 1500 * Arnaud Lahousse 5629-15-00
* Andy Laurez 1029 1700 * Andy Laurez 1029-17-00
* Corentin Lengelé 1475 1700 * Corentin Lengelé 1475-17-00
* Julien De Coninck 5613 1700 * Julien De Coninck 5613-17-00
The project's goal is to convert and optimize a python program in order to find the primes dividers of a list of numbers. The project's goal is to convert and optimize a python program in order to find the primes dividers of a list of numbers.
...@@ -68,6 +68,11 @@ make fact ...@@ -68,6 +68,11 @@ make fact
make test make test
``` ```
- To clean the directory use:
```bash
make clean
```
### Options ### Options
- `-N` : Determine the amount of threads to use - `-N` : Determine the amount of threads to use
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -7,14 +5,13 @@ ...@@ -7,14 +5,13 @@
#include <sys/types.h> #include <sys/types.h>
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include <math.h>
//for is_prime (need -lm for compilation)
#include <math.h>
int finished; int finished;
pthread_t *threads; pthread_t *threads;
//Struct for getopt args //struct for getopt args
typedef struct { typedef struct {
int verbose; int verbose;
int nThreads; int nThreads;
...@@ -22,32 +19,49 @@ typedef struct { ...@@ -22,32 +19,49 @@ typedef struct {
char* output_file; char* output_file;
}globalArgs; }globalArgs;
/*
* value -> value to compute
* dividers -> prime dividers of value
* length -> length of dividers array
*/
typedef struct prime_dividers{ typedef struct prime_dividers{
int length;
long long* dividers;
long long value; long long value;
long long* dividers;
int length;
}dividers_t; }dividers_t;
typedef struct queue{//implemented with a circular array /*
int size;//How many item inside * size -> current size of the queue
int sizeMax;//How many item maximum * sizeMax -> maximum size of the queue
long long *buffer;//Array useful to store all the value * buffer -> array used to store the values
int head;//index of the first element to pop out * head -> pointer to the head of the queue
int tail;//"index of the last element to pop out" ( index of a empty slot next to to last slot used ) * tail -> pointer to the tail of the queue
//PS: It's possible to delete one element because : head + size = tail */
typedef struct queue{
int size;
int sizeMax;
long long *buffer;
int head;
int tail;
}queue_t; }queue_t;
typedef struct div_queue{//implemented with a circular array /*
int size;//How many item inside * size -> current size of the queue
int sizeMax;//How many item maximum * sizeMax -> maximum size of the queue
dividers_t *buffer;//Array useful to store all the value * buffer -> array used to store the values
int head;//index of the first element to pop out * head -> pointer to the head of the queue
int tail;//"index of the last element to pop out" ( index of a empty slot next to to last slot used ) * tail -> pointer to the tail of the queue
//PS: It's possible to delete one element because : head + size = tail */
typedef struct div_queue{
int size;
int sizeMax;
dividers_t *buffer;
int head;
int tail;
}div_queue_t; }div_queue_t;
globalArgs Args; globalArgs Args;
int done = 1; int done = 1;
int done2; int done2;
queue_t* buffer; queue_t* buffer;
...@@ -69,30 +83,30 @@ int counter; ...@@ -69,30 +83,30 @@ int counter;
*/ */
queue_t* new_queue(){ queue_t* new_queue(){
int bufsize = (2* Args.nThreads) + 1; int bufsize = (2* Args.nThreads) + 1;
queue_t *result=malloc(sizeof(queue_t));// Malloc a memory space for the structure queue_t *result=malloc(sizeof(queue_t));
if(result==NULL){//Test malloc failure if(result==NULL){
printf("Malloc failed in newArray() for *result"); printf("Malloc failed in newArray() for *result");
return NULL; // Malloc fail return NULL;
} }
result->buffer = malloc(sizeof(long long) * bufsize);// malloc a memory space for the array of value result->buffer = malloc(sizeof(long long) * bufsize);
if(result->buffer==NULL){// Test malloc failure if(result->buffer == NULL){
printf("Malloc failed in newArray() for result->first"); printf("Malloc failed in newArray() for result->first");
free(result); free(result);
return NULL; // Malloc fail return NULL;
} }
//init basic values //init basic values
result->size=0; result->size = 0;
result->sizeMax = bufsize; result->sizeMax = bufsize;
result->head=0; result->head = 0;
result->tail=0; result->tail = 0;
return result; return result;
} }
void push(queue_t *queue, long long value){//Push value into the queue void push(queue_t *queue, long long value){
queue->buffer[queue->tail] = value; queue->buffer[queue->tail] = value;
queue->tail= (queue->tail + 1) % (queue->sizeMax); queue->tail= (queue->tail + 1) % (queue->sizeMax);
queue->size++; queue->size++;
...@@ -106,7 +120,7 @@ long long pop(queue_t *queue){ ...@@ -106,7 +120,7 @@ long long pop(queue_t *queue){
return result; return result;
} }
void free_queue(queue_t *queue){//Free a queue void free_queue(queue_t *queue){
free(queue->buffer); free(queue->buffer);
free(queue); free(queue);
} }
...@@ -118,33 +132,33 @@ void free_queue(queue_t *queue){//Free a queue ...@@ -118,33 +132,33 @@ void free_queue(queue_t *queue){//Free a queue
*/ */
div_queue_t* new_div_queue(){ div_queue_t* new_div_queue(){
int bufsize = (2* Args.nThreads) + 1; int bufsize = (2* Args.nThreads) + 1;
div_queue_t *result=malloc(sizeof(div_queue_t));// Malloc a memory space for the structure div_queue_t *result = malloc(sizeof(div_queue_t));
if(result==NULL){//Test malloc failure if(result==NULL){
printf("Malloc failed in newArray() for *result"); printf("Malloc failed in newArray() for *result");
return NULL; // Malloc fail return NULL;
} }
result->buffer = malloc(sizeof(dividers_t) * bufsize);// malloc a memory space for the array of value result->buffer = malloc(sizeof(dividers_t) * bufsize);
if(result->buffer==NULL){// Test malloc failure if(result->buffer == NULL){
printf("Malloc failed in newArray() for result->first"); printf("Malloc failed in newArray() for result->first");
free(result); free(result);
return NULL; // Malloc fail return NULL;
} }
//init basic values //init basic values
result->size=0; result->size = 0;
result->sizeMax = bufsize; result->sizeMax = bufsize;
result->head=0; result->head = 0;
result->tail=0; result->tail = 0;
return result; return result;
} }
void div_push(div_queue_t *queue, dividers_t value){//Push value into the queue void div_push(div_queue_t *queue, dividers_t value){
queue->buffer[queue->tail] = value; queue->buffer[queue->tail] = value;
queue->tail= (queue->tail + 1) % (queue->sizeMax); queue->tail = (queue->tail + 1) % (queue->sizeMax);
queue->size++; queue->size++;
} }
...@@ -155,7 +169,7 @@ dividers_t div_pop(div_queue_t *queue){ ...@@ -155,7 +169,7 @@ dividers_t div_pop(div_queue_t *queue){
return result; return result;
} }
void div_free_queue(div_queue_t *queue){//Free a queue void free_div_queue(div_queue_t *queue){//Free a queue
free(queue->buffer); free(queue->buffer);
free(queue); free(queue);
} }
...@@ -167,13 +181,11 @@ void printHelp(){ ...@@ -167,13 +181,11 @@ void printHelp(){
"\t-N\t\tspecify number of threads\n"); "\t-N\t\tspecify number of threads\n");
} }
// Return number modulo i int is_div(long long number, long long i){
int is_div(long long number,long long i){
return (number % i) == 0; return (number % i) == 0;
} }
// Pre: number > 0 // Pre: number > 0
// return true si number est Prime, false sinon
int is_prime(long long number){ int is_prime(long long number){
if( number == 1 || number == 0){ if( number == 1 || number == 0){
return false; return false;
...@@ -182,18 +194,28 @@ int is_prime(long long number){ ...@@ -182,18 +194,28 @@ int is_prime(long long number){
return true; return true;
for (long long i = 2; i <= ceill(sqrtl((long double) number)); i++){ for (long long i = 2; i <= ceill(sqrtl((long double) number)); i++){
if(is_div(number, i)) return false; if(is_div(number, i)){
return false;
}
} }
return true; return true;
} }
/*
* Find the prime dividers using the euclid method:
* A non-prime number is composed of prime factors
* Ex: 2 * 3 = 6
* Ex2: 2 * 3 * 5 = 30
* Ex3: 2 * 2 * 7 = 28
*/
void euclide(long long number, dividers_t* result, int index, long long last_div){ void euclide(long long number, dividers_t* result, int index, long long last_div){
if(number == 1){ if(number == 1){
return; return;
} }
for (long long i = last_div; i <= number ; i++) { for (long long i = last_div; i <= number ; i++) {
//find the first prime divider
if(number % i == 0 && is_prime(i)){ if(number % i == 0 && is_prime(i)){
//if the prime div is not already memorized
if(i != last_div){ if(i != last_div){
if(i == number && index == 0){ if(i == number && index == 0){
return; return;
...@@ -214,36 +236,33 @@ void euclide(long long number, dividers_t* result, int index, long long last_div ...@@ -214,36 +236,33 @@ void euclide(long long number, dividers_t* result, int index, long long last_div
dividers_t prime_divs(long long number){ dividers_t prime_divs(long long number){
dividers_t result; dividers_t result;
result.value = number; result.value = number;
result.length = 0; result.length = 0;
//max long long with the highest amount of prime = 2×3×5×7×11×13×17×19×23×29×31×37×41×43×47×53 = 3.25e19
//2×3×5×7×11×13×17×19×23×29×31×37×41×43×47×53 = 3.25e19
//max remember 16 elements //max remember 16 elements
result.dividers = malloc(sizeof(long long) * 16); result.dividers = malloc(sizeof(long long) * 16);
euclide(number,&result,0,1); euclide(number, &result, 0, 1);
return result; return result;
} }
void* produce(){ void* produce(){
FILE* fdIn = fopen(Args.input_file,"r"); FILE* fdIn = fopen(Args.input_file,"r");
if(fdIn == NULL){ if(fdIn == NULL){
printf("Open Error in main for fd\n"); printf("%s: FileNotFound\n", Args.input_file);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
char* line = NULL; char* line = NULL;
size_t len = 0; size_t len = 0;
char* eptr; char* eptr;
while (getline(&line, &len, fdIn) != -1){ while (getline(&line, &len, fdIn) != -1){
long long number = strtoll(line, &eptr,10); long long number = strtoll(line, &eptr,10);
if(number == 0){ if(number == 0){
printf("Conversion error string to ll\n"); printf("Conversion error string to long long\n");
} }
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("%lld \n", number); printf("Reading: %lld \n", number);
} }
if(number < 2){ if(number < 2){
...@@ -256,40 +275,30 @@ void* produce(){ ...@@ -256,40 +275,30 @@ void* produce(){
push(buffer, number); push(buffer, number);
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
sem_post(&full); sem_post(&full);
if (Args.verbose == 1){
printf("done = %d\n",done);
}
//end of critical area //end of critical area
} }
done = 0; done = 0;
fclose(fdIn); fclose(fdIn);
free(line); free(line);
return NULL; return NULL;
} }
void* compute(){ void* compute(){
while(done || buffer->size != 0 ) { while(done || buffer->size != 0 ) {
long long number; long long number;
//start of critical area
if (Args.verbose == 1){
printf("waiting compute\n");
}
//start of critical area
sem_wait(&full); sem_wait(&full);
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
number = pop(buffer); number = pop(buffer);
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("COMPUTING : %lld\n",number ); printf("COMPUTING : %lld\n", number );
} }
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
sem_post(&empty); sem_post(&empty);
//end of critical area //end of critical area
dividers_t result = prime_divs(number); dividers_t result = prime_divs(number);
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("COMPUTED : %lld\n", number); printf("COMPUTED : %lld\n", number);
} }
...@@ -299,60 +308,43 @@ void* compute(){ ...@@ -299,60 +308,43 @@ void* compute(){
pthread_mutex_lock(&mutex2); pthread_mutex_lock(&mutex2);
div_push(buffer2, result); div_push(buffer2, result);
counter--; counter--;
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("counter %d\n",counter ); printf("Still to compute: %d\n", counter);
} }
pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex2);
sem_post(&full2); sem_post(&full2);
//end of critical area
if (counter == 0){ if (counter == 0){
for (int i = Args.nThreads - 1; i >= 0 + finished;i--){ for (int i = Args.nThreads - 1; i >= 0 + finished; i--){
pthread_cancel(threads[i]); pthread_cancel(threads[i]);
} }
} }
printf("counter %d\n",counter );
if (Args.verbose == 1){
printf("done2 = %d\n",done2 );
}
//end of critical area
} }
return NULL; return NULL;
} }
void* consume(){ void* consume(){
FILE* fdOut = fopen(Args.output_file, "w"); FILE* fdOut = fopen(Args.output_file, "w");
if(fdOut == NULL){ if(fdOut == NULL){
printf("fopen Error in main for fdOut\n"); printf("Error creating %s\n", Args.output_file);
return NULL; return NULL;
} }
dividers_t result; dividers_t result;
//while (done2 || buffer2->size != 0){
while (counter || buffer2->size != 0){ while (counter || buffer2->size != 0){
//start of critical area //start of critical area
if (Args.verbose == 1){
printf("waiting consume\n");
}
sem_wait(&full2); sem_wait(&full2);
pthread_mutex_lock(&mutex2); pthread_mutex_lock(&mutex2);
result= div_pop(buffer2); result= div_pop(buffer2);
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("consumed : %lld\n",result.value);printf("counter %d\n",counter); printf("consumed : %lld\n", result.value);
printf("counter %d\n", counter);
} }
fprintf(fdOut, "%lld", result.value); fprintf(fdOut, "%lld", result.value);
if (result.length != 0){ if (result.length != 0){
for(int i = 0; i<result.length; i++){ for(int i = 0; i < result.length; i++){
fprintf(fdOut, " %lld", result.dividers[i]); fprintf(fdOut, " %lld", result.dividers[i]);
} }
} }
...@@ -360,9 +352,8 @@ void* consume(){ ...@@ -360,9 +352,8 @@ void* consume(){
free(result.dividers); free(result.dividers);
pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex2);
sem_post(&empty2); sem_post(&empty2);
//end of critical area
} }
fclose(fdOut); fclose(fdOut);
return NULL; return NULL;
} }
...@@ -3,21 +3,19 @@ ...@@ -3,21 +3,19 @@
#include "functions.c" #include "functions.c"
int main(int argc, char** argv){ int main(int argc, char** argv){
Args.nThreads = 8; //default number of threads //default number of threads
Args.nThreads = 8;
//getOpt //getOpt
const char* strOpts = "hvN:"; const char* strOpts = "hvN:";
const struct option longOpts[] = { const struct option longOpts[] = {
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"verbose", no_argument, NULL, 'v'} {"verbose", no_argument, NULL, 'v'}
}; };
int opt; int opt;
int longIndex; int longIndex;
while ( (opt = getopt_long(argc, argv, strOpts, longOpts, &longIndex)) != -1){ while ((opt = getopt_long(argc, argv, strOpts, longOpts, &longIndex)) != -1){
switch(opt){ switch(opt){
case 'h': case 'h':
printHelp(); printHelp();
...@@ -37,68 +35,63 @@ int main(int argc, char** argv){ ...@@ -37,68 +35,63 @@ int main(int argc, char** argv){
printf("Number of Threads : %d\n", Args.nThreads ); printf("Number of Threads : %d\n", Args.nThreads );
} }
//count number of Line //count number of line
FILE* LineCounter = fopen(Args.input_file,"r"); FILE* line_counter = fopen(Args.input_file, "r");
if(LineCounter == NULL){ if(line_counter == NULL){
printf("Open Error in main for fd LineCounter\n"); printf("%s: FileNotFound\n", Args.input_file);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
counter = 0; counter = 0;
char* line = NULL; char* line = NULL;
size_t len = 0; size_t len = 0;
while (getline(&line, &len, LineCounter)!=-1){ while (getline(&line, &len, line_counter) != -1){
counter++; counter++;
} }
fclose(line_counter);
fclose(LineCounter);
free(line); free(line);
if (Args.verbose == 1){ //limit number of thread to have 1 thread per line
printf("counter BEFORE : %d\n",counter );
}
if (counter < Args.nThreads){ if (counter < Args.nThreads){
Args.nThreads = counter; Args.nThreads = counter;
} }
done2 = Args.nThreads; done2 = Args.nThreads;
buffer = new_queue(); buffer = new_queue();
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
sem_init (&empty,0,(2* Args.nThreads) +1); sem_init (&empty, 0, (2* Args.nThreads) +1);
sem_init(&full,0,0); sem_init(&full, 0, 0);
buffer2 = new_div_queue(); buffer2 = new_div_queue();
pthread_mutex_init(&mutex2,NULL); pthread_mutex_init(&mutex2, NULL);
sem_init (&empty2,0,(2* Args.nThreads) +1); sem_init (&empty2, 0, (2* Args.nThreads) +1);
sem_init(&full2,0,0); sem_init(&full2, 0, 0);
int* error; int* error;
pthread_t reader; pthread_t reader;
pthread_t writer; pthread_t writer;
//pthread_t threads[Args.nThreads];
threads = malloc(sizeof(pthread_t) * Args.nThreads); threads = malloc(sizeof(pthread_t) * Args.nThreads);
if(threads == NULL){ if(threads == NULL){
printf("Malloc error for threads in main\n"); printf("Malloc error for threads in main\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
finished = 0; finished = 0;
//produce function
if (pthread_create(&reader, NULL, &produce, NULL) != 0){ if (pthread_create(&reader, NULL, &produce, NULL) != 0){
printf("Error while creating the reader thread\n"); printf("Error while creating the reader thread\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
//coumpute function
// coumpute fonction
for(int i =0; i<Args.nThreads; i++){ for(int i =0; i<Args.nThreads; i++){
if(pthread_create(&threads[i], NULL, &compute, NULL) != 0){ if(pthread_create(&threads[i], NULL, &compute, NULL) != 0){
printf("Error while creating one of the computing threads\n"); printf("Error while creating one of the computing threads\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
//consume function
//consume fonction
if (pthread_create(&writer, NULL, &consume, NULL) != 0){ if (pthread_create(&writer, NULL, &consume, NULL) != 0){
printf("Error while creating the writer thread\n"); printf("Error while creating the writer thread\n");
return EXIT_FAILURE; return EXIT_FAILURE;
...@@ -109,7 +102,6 @@ int main(int argc, char** argv){ ...@@ -109,7 +102,6 @@ int main(int argc, char** argv){
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("------------ joined reader ---------------\n"); printf("------------ joined reader ---------------\n");
} }
...@@ -120,15 +112,14 @@ int main(int argc, char** argv){ ...@@ -120,15 +112,14 @@ int main(int argc, char** argv){
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("---------------------------------one thread finished\n"); printf("--------------------------one thread finished\n");
} }
finished++; finished++;
} }
done2 = 0;
done2=0;
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("------------- joined compute ------------\n"); printf("------------- joined compute -------------\n");
} }
if(pthread_join(writer, (void**) &error) != 0){ if(pthread_join(writer, (void**) &error) != 0){
...@@ -136,12 +127,10 @@ int main(int argc, char** argv){ ...@@ -136,12 +127,10 @@ int main(int argc, char** argv){
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("---------------- join consume ---------------------\n"); printf("------------- join consume -------------\n");
} }
sem_destroy(&full); sem_destroy(&full);
sem_destroy(&empty); sem_destroy(&empty);
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
...@@ -152,11 +141,11 @@ int main(int argc, char** argv){ ...@@ -152,11 +141,11 @@ int main(int argc, char** argv){
sem_destroy(&full2); sem_destroy(&full2);
sem_destroy(&empty2); sem_destroy(&empty2);
pthread_mutex_destroy(&mutex2); pthread_mutex_destroy(&mutex2);
div_free_queue(buffer2); free_div_queue(buffer2);
if (Args.verbose == 1){ if (Args.verbose == 1){
printf("Success end"); printf("Success end");
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
\ 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