diff --git a/Code_With_Threads/fonctions.c b/Code_With_Threads/fonctions.c
new file mode 100644
index 0000000000000000000000000000000000000000..10d0b19e8c863435deea2d4240c89e953a29c6e7
--- /dev/null
+++ b/Code_With_Threads/fonctions.c
@@ -0,0 +1,235 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+
+#include "fonctions.h"
+
+/*
+Initialise une liste de node contenant un entier
+*/
+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 contenant une liste
+*/
+void init_list_lst(list_lst *my_list) {
+    my_list->first = NULL;
+    my_list->last = NULL;
+    my_list->length = 0;
+}
+
+/*
+Ajoute un node contenant un entier à la fin d'une liste
+*/
+void put_node_t(list_t *my_list, int 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 contenant une liste à la fin d'une liste
+*/
+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 d'une liste et renvoit son entier
+*/
+int 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 d'une liste et renvoit sa liste
+*/
+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;
+}
+
+/*
+Renvoit l'entier d'un node situé à une position donnée
+*/
+int get_at_index(list_t *my_list, int index) {
+    if (my_list->length < index || index < 0) return -1;
+    node_t *temp = my_list->first;
+    for (int i = 0; i < index; i++) {
+        temp = temp->next;
+    }
+    return temp->value;
+}
+
+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;
+}
+
+void clear_list_lst(list_lst *my_list) {
+    if (my_list->length == 0) return;
+    while (my_list->length != 0) {
+        list_t *temp = get_node_lst(my_list);
+        clear_list_t(temp);
+        free(temp);
+    }
+}
+
+list_t *prime_list(int value) {
+    list_t *prime = malloc(sizeof(list_t));
+    if (!prime) return NULL;
+    init_list_t(prime);
+    put_node_t(prime, value);
+    
+    int in_node = 0;
+    int chiffre = value;
+
+    while (value % 2 == 0) {
+        if (2 != in_node) {
+            put_node_t(prime, 2);
+            in_node = 2;
+        }
+        value = value/2;
+    }
+    for (int 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;
+}
+
+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;
+}
+
+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;
+}
+
+int count_lines(char *filename){
+    int number;
+    int lines = 0;
+    FILE *file = fopen(filename, "r");
+    while (fscanf(file, "%d", &number) != EOF) {
+        lines++;
+    }
+    fclose(file);
+    return lines;
+}
\ No newline at end of file