diff --git a/Final Code/fonctions.c b/Final Code/fonctions.c new file mode 100644 index 0000000000000000000000000000000000000000..6e3ce8cc89799fb427a841206a533b807dcb18a1 --- /dev/null +++ b/Final Code/fonctions.c @@ -0,0 +1,246 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <unistd.h> +#include <stdint.h> + +#include <pthread.h> +#include <semaphore.h> + +#include "fonctions.h" + +/* +Initialise une liste de node_t +@my_list : la list_t qui est initialisée +*/ +void init_list_t(list_t *my_list) { + my_list->first = NULL; + my_list->last = NULL; + my_list->length = 0; +} + +/* +Initialise une liste de node_lst +@my_list : la list_lst qui est initialisée +*/ +void init_list_lst(list_lst *my_list) { + my_list->first = NULL; + my_list->last = NULL; + my_list->length = 0; +} + +/* +Ajoute un node_t à la fin d'une list_t +@my_list : la list_t a laquelle on va ajouter un node_t +@value : la valeur (uint64_t) que contiendra le node_t +*/ +void put_node_t(list_t *my_list, uint64_t value) { + node_t *new = malloc(sizeof(node_t)); + if (!new) return; + new->next = NULL; + new->value = value; + if (my_list->length == 0) { + my_list->first = new; + my_list->last = new; + } else { + my_list->last->next = new; + my_list->last = new; + } + my_list->length += 1; +} + +/* +Ajoute un node_lst à la fin d'une list_lst +@my_list : la list_lst a laquelle on va ajouter un node_lst +@put_list : la list_t que contiendra le node_lst +*/ +void put_node_lst(list_lst *my_list, list_t *put_list) { + node_lst *new = malloc(sizeof(node_lst)); + if (!new) return; + new->next = NULL; + new->diviseurs = put_list; + if (my_list->length == 0) { + my_list->first = new; + my_list->last = new; + } else { + my_list->last->next = new; + my_list->last = new; + } + my_list->length += 1; +} + +/* +Retire le premier node_t d'une list_t et renvoit son entier +@my_list : la list_t de laquelle on va retier le node_t pointé par first +@return : la valeur (uint64_t) que contenait le node_t retiré +*/ +uint64_t get_node_t(list_t *my_list) { + if (my_list->length == 0) return -1; + int value = my_list->first->value; + node_t *temp = my_list->first; + my_list->first = my_list->first->next; + my_list->length -= 1; + free(temp); + return value; +} + +/* +Retire le premier node_lst d'une list_lst et renvoit sa liste +@my_list ; la list_lst de laquelle on va retirer le node_lst pointé par first +@return : la liste (list_t) que contenait le node_lst retiré +*/ +list_t *get_node_lst(list_lst *my_list) { + if (my_list->length == 0) return NULL; + list_t *get_list = my_list->first->diviseurs; + node_lst *temp = my_list->first; + my_list->first = my_list->first->next; + my_list->length -= 1; + free(temp); + return get_list; +} + +/* +Vide une list_t de node_t +@my_list : la list_t qui va être vidée +*/ +void clear_list_t(list_t *my_list) { + if (my_list == NULL || my_list->length == 0) return; + node_t *temp = my_list->first->next; + while(my_list->first != NULL) { + free(my_list->first); + my_list->first = temp; + if (temp != NULL) { + temp = temp->next; + } + } + my_list->first = NULL; +} + +/* +Renvoie une list_t contenant un nombre suivi de ses diviseurs premiers +@value : le nombre (uint64_t) dont on veut trouver les diviseurs premiers +@return : une list_t contenant value dans le node_t pointé par first ainsi que ses diviseurs premiers +*/ +list_t *prime_list(uint64_t value) { + list_t *prime = malloc(sizeof(list_t)); + if (!prime) return NULL; + init_list_t(prime); + put_node_t(prime, value); + + uint64_t in_node = 0; + uint64_t chiffre = value; + uint64_t div = 2; + + while (value % div == 0) { + if (div != in_node && value != div) { + put_node_t(prime, div); + in_node = div; + } + value = value/div; + } + for (uint64_t i = 3; i*i <= value; i += 2) { + while (value % i == 0) { + if (i != in_node) { + put_node_t(prime, i); + in_node = i; + } + value = value / i; + } + } + if (value != chiffre && value != 1){ + put_node_t(prime, value); + } + + return prime; +} + +/* +Compte les lignes d'un fichier +@filename : un pointeur vers le nom du fichier à ouvrir +@return : le nombre (int) de lignes dans le fichier donné +*/ +int count_lines(char *filename){ + uint64_t number; + int lines = 0; + FILE *file = fopen(filename, "r"); + while (fscanf(file, "%lu", &number) != EOF) { + lines++; + } + fclose(file); + return lines; +} + +/* +Initialise un buffer1 +@nthreads : le nombre (int) de threads passé en argument du programme +@return : un pointeur vers un buffer1 initialisé +*/ +buffer1 *init_buffer_1(int nthreads) { + buffer1 *buffer_1 = malloc(sizeof(buffer1)); + if (!buffer_1) { + free(buffer_1); + return NULL; + } + + if (pthread_mutex_init(&(buffer_1->mutex), NULL) == -1) { + free(buffer_1); + return NULL; + } + if (sem_init(&(buffer_1->free), 0, nthreads + 2) == -1) { + free(buffer_1); + return NULL; + } + if (sem_init(&(buffer_1->full), 0, 0) == -1) { + free(buffer_1); + return NULL; + } + + buffer_1->can_stop = false; + buffer_1->numbers = malloc(sizeof(list_t)); + if (!buffer_1->numbers) { + free(buffer_1->numbers); + free(buffer_1); + return NULL; + } + + init_list_t(buffer_1->numbers); + + return buffer_1; +} + +/* +Initialise un buffer2 +@nthreads : le nombre (int) de threads passé en argument du programme +@return : un pointeur vers un buffer2 initialisé +*/ +buffer2 *init_buffer_2(int nthreads) { + buffer2 *buffer_2 = malloc(sizeof(buffer2)); + if (!buffer_2) { + free(buffer_2); + return NULL; + } + + if (pthread_mutex_init(&(buffer_2->mutex), NULL) == -1) { + free(buffer_2); + return NULL; + } + if (sem_init(&(buffer_2->free), 0, nthreads + 2) == -1) { + free(buffer_2); + return NULL; + } + if (sem_init(&(buffer_2->full), 0, 0) == -1) { + free(buffer_2); + return NULL; + } + + buffer_2->prime_numbers = malloc(sizeof(list_lst)); + if (!buffer_2->prime_numbers) { + free(buffer_2->prime_numbers); + free(buffer_2); + return NULL; + } + + init_list_lst(buffer_2->prime_numbers); + + return buffer_2; +} \ No newline at end of file