Skip to content
Extraits de code Groupes Projets

Master

Ouvert Giovanna Stefanelli a demandé de fusionner stefanelli/projet3_first_pull_request:master vers master
1 fichier
+ 224
0
Comparer les modifications
  • Côte à côte
  • En ligne
+ 224
0
//
#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#include <time.h>
#include <pthread.h>
/* STRUCTURES AND VARIABLES */
/* "struct factorization"
* "prime_dividers" is an array containing max N dividers
* "cnt" is the number of calculated dividers
* "number" is number to calculate the prime dividers
*/
#define N 8 // Max number of dividers in the buffer
typedef struct factorization {
unsigned long prime_dividers[N];
unsigned int cnt;
unsigned long number;
} factor;
/* struct file_descriptors
* "in" is the inputfile file descriptor
* "out" is the outputfile file descriptor
* "options" "v" (verbose) with debugging information, "q" without debugging information
*/
typedef struct file_descriptors {
FILE *in;
FILE *out;
// char options; // For internal command test
} fd;
// Declare f (type fd). Structure containing the file descriptors
fd f;
/* MUTEX */
pthread_mutex_t mutex_readwrite; // define mutex variable
/*
* FUNCTIONS used in the programme:
* bool is_div(unsigned long, unsigned long);
* bool is_prime(unsigned long);
* factor *prime_divs(unsigned long);
* void *read_write(fd);
*/
bool is_div(unsigned long numbr, unsigned long i){
if((numbr % i) == 0) { // verify if i is the divider of numbr
return(true); // i is a divider of numbr
} else {
return(false); // i is not a divider of numbr
}
}
bool is_prime(unsigned long nbr) {
/*
* Optimised solution with less loop, see: https://fr.wikipedia.org/wiki/Nombre_premier
* "Crible d'Ératosthène:
* Les premiers algorithmes pour décider si un nombre est premier
* (appelés tests de primalité) consistent à essayer de le diviser par tous les nombres
* qui n'excèdent pas sa racine carrée"
*/
// for(unsigned long j = 2; j <= nbr; j++) { // OLD SOLUTION LESS EFFICIENT
for (unsigned long j = 2; j <= sqrt(nbr); j++) {
if ((nbr % j) == 0) { // verify if i is the divider of nbr
return (false); // i is a divider of nbr
}
}
return (true); // i is a prime number
}
factor* prime_divs (unsigned long numbr) {
factor *dividers; // Structure storing dividers and their number
/* Allocation of memory for "struct factor" and
* initialization the "dividers" struture to zero */
dividers = (factor *) calloc(1, sizeof(factor));
unsigned int n = 0;
dividers->number = numbr;
unsigned long tmp_number = dividers->number;
//for(unsigned long i = 2; i < number; i++) { //Old python approach
//for(unsigned long i = 2; i <number; i++) {
for(unsigned long i = 2; i <= tmp_number ; i++) {
if(is_div(dividers->number,i) == true){
if(is_prime(i) == true){
dividers->prime_dividers[n] = i;
/* The max numbers of loops is reduced
* from "number" to "tmp_number/i" */
tmp_number = tmp_number/i;
if(i != dividers->number) {
n++;
}
}
}
}
dividers->cnt = n;
return(dividers);
}
void *read_write() {
factor *dividers;
unsigned long number;
// Read input file line by line till the end of file (eof)
while (!feof(f.in)) {
fscanf(f.in, "%lu\n", &number); // Read number to be factored
/* Verify if the number is prime or not, in this case the dividers are calculated */
dividers = prime_divs(number); // Core function of the app //
/* MUTEX LOCK - CONTROL OF CRITICAL ACCESS - START */
if (pthread_mutex_lock(&mutex_readwrite) != 0) {
printf("\nmutex_lock-mutex_readwrite %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (dividers->cnt != 0) {
fprintf(f.out, "%lu ", dividers->number);
for (int i = 0; i < dividers->cnt; i++) {
fprintf(f.out, " %lu", dividers->prime_dividers[i]);
}
} else { // For internal command test
fprintf(f.out, "%lu ", dividers->number);
}
/* MUTEX UNLOCK - CONTROL OF CRITICAL ACCESS - END */
if (pthread_mutex_unlock(&mutex_readwrite) != 0) {
printf("\nmutex_lock-mutex_readwrite %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(f.out, "\n");
free(dividers);
}
pthread_exit((void *) 0); // thread exit: normal termination => 0
}
#define DEFAULT_NO_THREADS 2
#define MAX_NO_THREADS 20
// MAIN PROGRAMME
int main (int argc, char *argv[]) {
// Input arguments
char *inputfile; // Input filemane (string)
char *outputfile; // Output filemane (string)
char *thread_arg; //
int NO_THREADS = DEFAULT_NO_THREADS; // Define default number of threads
if (argc == 3) { // Check if the number of argument is correct
inputfile = argv[1];
outputfile = argv[2];
printf("Thread Number not mentioned\n");
printf("The threads default number is %d\n", DEFAULT_NO_THREADS);
} else if(argc == 5) {
thread_arg = argv[1];
if(strcmp(thread_arg, "-N") != 0) {
printf("%s\n", "Wrong input of the option \"-N\"\n");
exit(EXIT_FAILURE);
}
NO_THREADS = atoi(argv[2]);
if(NO_THREADS > MAX_NO_THREADS) {
printf("Threads requested > %d\n", MAX_NO_THREADS);
exit(EXIT_FAILURE);
}
inputfile = argv[3];
outputfile = argv[4];
} else {
printf("%s\n", "Many or few arguments\n");
printf("Correct command syntax:\n");
printf("./programme [-N number_of_threads] inputfile.txt outputfile.txt");
exit(EXIT_FAILURE);
}
/*
* START CLOCK to measure CPU time
* calculate programme performance
*/
clock_t start, end;
double cpu_time_used;
start = clock();
/* For internal control test
system("pwd"); // Current directory
printf("\n -- Programme start --\n");
printf(" nr arguments: %d\n", argc);
printf("Thread activated no. %d\n",NO_THREADS);
printf(" input file: %s\n", inputfile);
printf(" output file: %s\n", outputfile);
printf(" option: %c\n", f.options);
*/
// Open input and output files
f.in = fopen(inputfile, "r");
f.out = fopen(outputfile, "a+");
if ((f.in == NULL) || (f.out == NULL)) {
printf("Incorrect inputfile or outputfile name\n");
exit(EXIT_FAILURE);
}
pthread_t thread[NO_THREADS]; // thread IDs
// INITIALIZE MUTEX "mutex_readwrite"
if (pthread_mutex_init(&mutex_readwrite , NULL) != 0){
printf("\n mutex init failed-mutex_readwrite\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i < NO_THREADS; i++) {
pthread_create(&thread[i], NULL, (void*)read_write, NULL);
}
for (int i = 0; i < NO_THREADS; i++) {
pthread_join(thread[i], NULL);
}
/* END CLOCK to measure CPU time */
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
fprintf(f.out, "\nThe programme execution needed %.3f seconds\n\n", cpu_time_used);
printf("\nThe programme execution needed %.3f seconds", cpu_time_used);
printf("\n -- Programme end --\n");
// Eliminate mutex "mutex_readwrite"
if (pthread_mutex_destroy(&mutex_readwrite) != 0){
printf("\nmutex_destroy-mutex_readwrite %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fclose(f.in);
fclose(f.out);
return (EXIT_SUCCESS);
}
Chargement en cours