#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); printf ("Error with buffer_1.\n"); 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); printf ("buffer_1 created.\n"); 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); printf ("Error with buffer_2.\n"); 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); printf ("buffer_2 created.\n"); return buffer_2; }