Skip to content
Extraits de code Groupes Projets
fonctions.c 6,19 ko
Newer Older
  • Learn to ignore specific revisions
  • Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include <unistd.h>
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    #include <stdint.h>
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    
    #include <pthread.h>
    #include <semaphore.h>
    
    #include "fonctions.h"
    
    /*
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    Initialise une liste de node_t
    @my_list : la list_t qui est initialisée
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    */
    void init_list_t(list_t *my_list) {
        my_list->first = NULL;
        my_list->last = NULL;
        my_list->length = 0;
    }
    
    /*
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    Initialise une liste de node_lst
    @my_list : la list_lst qui est initialisée
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    */
    void init_list_lst(list_lst *my_list) {
        my_list->first = NULL;
        my_list->last = NULL;
        my_list->length = 0;
    }
    
    /*
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    Ajoute un node_t à la fin d'une list_t
    @my_list : la list_t a laquelle on va ajouter un node_t
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    @value : la valeur (uint64_t) que contiendra le node_t
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    */
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    void put_node_t(list_t *my_list, uint64_t value) {
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
        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;
    }
    
    /*
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    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
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    */
    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;
    }
    
    /*
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    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
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    @return : la valeur (uint64_t) que contenait le node_t retiré
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    */
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    uint64_t get_node_t(list_t *my_list) {
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
        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;
    }
    
    /*
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    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é
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    */
    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;
    }
    
    /*
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    Vide une list_t de node_t
    @my_list : la list_t qui va être vidée
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    */
    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;
    }
    
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    /*
    Renvoie une list_t contenant un nombre suivi de ses diviseurs premiers
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    @value : le nombre (uint64_t) dont on veut trouver les diviseurs premiers
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    @return : une list_t contenant value dans le node_t pointé par first ainsi que ses diviseurs premiers
    */
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    list_t *prime_list(uint64_t value) {
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
        list_t *prime = malloc(sizeof(list_t));
        if (!prime) return NULL;
        init_list_t(prime);
        put_node_t(prime, value);
    
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
        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;
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
            }
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
            value = value/div;
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
        }
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
        for (uint64_t i = 3; i*i <= value; i += 2) {
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
            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;
    }
    
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    /*
    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;
    }
    
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    /*
    Initialise un buffer1
    @nthreads : le nombre (int) de threads passé en argument du programme
    @return : un pointeur vers un buffer1 initialisé
    */
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    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;
    }
    
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    /*
    Initialise un buffer2
    @nthreads : le nombre (int) de threads passé en argument du programme
    @return : un pointeur vers un buffer2 initialisé
    */
    
    Arnaud Lefebvre's avatar
    Arnaud Lefebvre a validé
    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;
    }