Skip to content
Extraits de code Groupes Projets
run.c 13,9 ko
Newer Older
  • Learn to ignore specific revisions
  • Laurent Paucot's avatar
    Laurent Paucot a validé
    #include "run.h"
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    #define uint_64 unsigned long long
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
    void put_in_buffer_1(char *c, struct buffer_rc *ptr){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Ajout d'un element dans le buffer 1
        Pré : *c un pointeur de type 'char', *ptr un pointeur vers une structure 'buffer_rc'
        Post : /
        */
        ptr->tab[ptr->head] = malloc(sizeof(char)*(strlen(c) + 1)); //allocation de la taille de la chaine
    
        if(ptr->tab[ptr->head] ==NULL){return;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        strcpy(ptr->tab[ptr->head],c);          
        ptr->len++;                             //augmenter l'espace occupé de 1
        ptr->head = (ptr->head + 1)%ptr->size;  //faire avancer le pointeur de 1 (modulo N pour ne pas dépasser N)
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
    char *get_from_buffer_1(struct buffer_rc *ptr){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Récupération d'une chaine de caractères dans le buffer 1
        Pré : *ptr un pointeur vers une structure 'buffer_rc'
        Post : un pointeur vers la chaine de caractères récupérée
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        char *result;
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
        result = ptr->tab[ptr->tail];
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr->tab[ptr->tail] = NULL;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr->len--;                     
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr->tail = (ptr->tail + 1)%ptr->size;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return result;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
    void put_in_buffer_2(struct queue *ptr, struct buffer_cw *buf){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Ajout d'un element dans le buffer 2
        Pré : *ptr un pointeur vers une liste, *buf un pointeur vers uen structure 'buffer_cw'
        Post : /
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->tab[buf->head] = ptr;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->len++;        
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->head = (buf->head + 1)%buf->size;
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
    queue_t *get_from_buffer_2(struct buffer_cw *buf){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        récupération d'une liste dans le buffer 2
        Pré : *buf un pointeur vers une structure 'buffer_cw'
        Post : un pointeur vers la liste récupérée dans le buffer 'buf'
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct queue *result;
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
        result = buf->tab[buf->tail];
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->tab[buf->tail] = NULL;
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
        buf->len--;  //diminue l'espace occupé par le buffer
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->tail = (buf->tail + 1)%buf->size;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return result;
    }
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
    int is_div(uint_64 number, uint_64 i) {
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /* 
        Vérifie si i est un diviseur de number 
        Pré : number et i des entiers
        Post : 1 si number est divisible par i, 0 sinon
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (i == 0){return 0;}
    
    Raphaël Ngenyi-Ngondo's avatar
    Raphaël Ngenyi-Ngondo a validé
        return (number % i == 0) ;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    uint_64 modpow (uint_64 base, uint_64 exp, uint_64 mod){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /* 
        algorithme d'exponentiation modulaire (calcul de puissances entières)
        Pré : base, exp et mod des entiers
        Post : renvoie base^exp modulo (mod)
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        uint_64 result = 1;
        while (exp > 0)
        {
            if ((exp & 1) > 0) {
                result = (result * base) % mod;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            exp >>= 1;      
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            base = (base * base) % mod;
    
        return result;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    uint_64* randomiser (int k, uint_64 N){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /* 
        Génération de nombres aléatoires
        Pré : k et N des entiers
        Post : un pointeur vers k entiers compris entre 1 et N 
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        uint_64 *result;
        result = malloc(sizeof(uint_64)*k);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        srand(time(NULL));                  // initialisation du générateur de nombre aléatoire par la fonction time
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (int i = 0; i < k; i++)
        {
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            result[i] = rand() % (N-1) +1;  
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        }
        return result;
    }
    
    int is_prime (uint_64 number){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Vérifie si number est premier au moyen du test de Fermat
        Pré : number un entier
        Post : 1 si number est premier, 0 sinon
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        uint_64 *random;
        int k;
        if (number <= 20){k = number-1;}
        else{k = 20;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        random = randomiser(k,number); // génère k nombres aléatoires
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (int i = 0; i < k; i++)
        {
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            if (modpow(random[i],number-1,number) == 1)  //test de Fermat
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                continue;                         //tant qu'on pas montré que number était composé on continue   
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            else{
                free(random);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                return 0;            
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        free(random);
        return 1;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void enqueue(queue_t* q, uint_64 val){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /* 
        Ajoute un nouveau noeud contenant val à la queue
        Pré : q un pointeur vers la liste de type 'queue_t', val un entier
         */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct node *ptr;
        ptr = malloc(sizeof(node_t));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (ptr == NULL){return;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr->value = val;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (q->size == 0)               //cas où la liste est vide
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            q->tail = ptr;
            ptr->next = ptr;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        else{                           //cas de base
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            ptr->next = q->tail->next;
            q->tail->next = ptr;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        }
        q->size++;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    queue_t* prime_divs(uint_64 number){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        calcule et crée la liste des diviseurs premiers d'un nombre
        Pré : number un entier
        Post : un pointeur de type 'queue_t' vers la liste des diviseurs premiers de nummber
        */
        queue_t *ptr;              //création de la liste
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr = malloc(sizeof(queue_t));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (ptr == NULL){
            free(ptr);
            return NULL;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr->size = 0;
        ptr->final = 0;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (uint_64 i = 2; i <= number/2; i++){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            if (is_div(number, i) && is_prime(i) == 1){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                enqueue(ptr,i);     //si i est diviseur de number et premier, il est ajouté à la liste
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        enqueue(ptr,number);        //le nombre à factoriser est également rajouté à la liste
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
        return ptr;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    }
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void *writing(void *param){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Ecriture dans le fichier de sortie
        Pré : param un pointeur de type 'void'
        Post : //
        */
        struct buffer_cw *param1 = (struct buffer_cw *) param;  
        int stop = 0;   //compteur des threads de calculs ayant fini de travailler
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        while(1){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            sem_wait(&full2);
            pthread_mutex_lock(&mutex2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            queue_t *pr_divs = get_from_buffer_2(param);    //récupération de la liste de diviseurs
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pthread_mutex_unlock(&mutex2);
    
            sem_post(&empty2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            if (pr_divs->final == 1)        //si la liste est finale (insérée par un thread de calcul en fin de traavil)
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                if (stop == N-1)            //si tous les threads de calcul ont fini
                {           
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                    free(pr_divs);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                    free(param1->tab);
    
                    return NULL;
                }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                free(pr_divs);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                stop++;                     //un thread de calcul supplémentaire a fini de travailler
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            else
            {
    
                FILE *file2 = param1->file2;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                node_t *current;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                current = pr_divs->tail;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                current = current->next;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                fprintf(file2,"%llu",current->value);    //écriture du nombre à factoriser
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                node_t *toFree = current;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                current = current->next;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                for (int i = 1; i < pr_divs->size; i++)
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                    free(toFree);
                    toFree = current;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                    fprintf(file2," %llu",current->value);   //écriture des diviseurs premiers
    
                    current = current->next;
                }
                fputc('\n',file2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                free(pr_divs->tail);
                free(pr_divs);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        }
        return NULL;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    void *calculating(void *param){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Récupère les chaines du buffer 1, effectue les calculs et replace les listes de diviseurs dans le buffer 2
        Pré : param, un pointeur de type 'void'
        Post : /
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct buffer_rccw *param1 = (struct buffer_rccw *) param;
        struct buffer_rc *buffer_1 = param1->struct1;
        struct buffer_cw *buffer_2 = param1->struct2;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        while(1){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            sem_wait(&full1);
            pthread_mutex_lock(&mutex1);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            char *chaine = get_from_buffer_1(buffer_1);     //Récupération de la chaine
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pthread_mutex_unlock(&mutex1);
    
            sem_post(&empty1);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            
            if (strcmp("stop",chaine) == 0) // arrêt des threads de calcul
    
                struct queue *final;
                final = malloc(sizeof(queue_t));
                if (final == NULL){return NULL;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                final->final = 1;           //pour indiquer au thread d'écriture qu'il a fini de travailler
                
    
                sem_wait(&empty2);
                pthread_mutex_lock(&mutex2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                put_in_buffer_2(final,buffer_2);    //insertion dans le buffer 2
    
                pthread_mutex_unlock(&mutex2);
                sem_post(&full2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                free(chaine);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
                return NULL;
            }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            uint_64 number;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            number = strtoll(chaine,NULL,0); //conversion de la chaine en long long
            if (number != 0 || strcmp("0\n",chaine) == 0)   //au cas où la conversion échoue
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            struct queue *pr_divs;
    
            pr_divs = prime_divs(number);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            sem_wait(&empty2);
            pthread_mutex_lock(&mutex2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            put_in_buffer_2(pr_divs,buffer_2);      //insertion dans le buffer 2
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pthread_mutex_unlock(&mutex2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            sem_post(&full2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            free(chaine);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return NULL;
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void *reading (void *param){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Fonction qui lit un fichier d'entrée
        Pré : param, un pointeur de type 'void'
        Post : /
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct buffer_rc *param1= (struct buffer_rc *) param;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        char chaine[30];
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        FILE *input;
        input = param1->file1;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        while (fgets(chaine,30,input) != NULL){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            sem_wait(&empty1);
            pthread_mutex_lock(&mutex1);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            put_in_buffer_1(chaine,param1);            //insère chaque ligne dans le buffer 1
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pthread_mutex_unlock(&mutex1);
            sem_post(&full1);
        }
    
    
        for (int i = 0; i < N; i++)
        {
            sem_wait(&empty1);
            pthread_mutex_lock(&mutex1);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            put_in_buffer_1("stop\0",param1);            //insère autant de chaine "stop" que de threads de calcul
    
            pthread_mutex_unlock(&mutex1);
            sem_post(&full1);
        }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return NULL;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void sem_1_initializer(struct buffer_rc *buf){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Initialisation du sémaphore du buffer 1
        Pré : buf, pointeur vers une structure 'buffer_rc'
        Post : /
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        pthread_mutex_init(&mutex1,NULL);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        sem_init(&empty1,0,buf->size);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        sem_init(&full1,0,0);
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void sem_2_initializer (struct buffer_cw *buf){
        /*
        Initialisation du sémaphore du buffer 2
        Pré : buf, pointeur vers une structure 'buffer_cw'
        Post : /
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        pthread_mutex_init(&mutex2,NULL);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        sem_init(&empty2,0,buf->size);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        sem_init(&full2,0,0);
    }
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    struct buffer_rc * buff_init_1(FILE *file1){
        /*
        Initialisation du buffer 1
        Pré : file1, un pointeur de type 'FILE'
        Post : pointeur vers une structure 'buffer_rc'
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct buffer_rc *ptr1;
        ptr1 = malloc(sizeof(struct buffer_rc));
        if (ptr1 == NULL){
            free(ptr1);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            return NULL;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr1->tab = malloc(2*N*sizeof(char*));  //tableau de taille 2*N
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr1->size = 2*N;
        ptr1->len = 0;
        ptr1->head = 0;
        ptr1->tail = 0;
        ptr1->file1 = file1;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return ptr1;
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    struct buffer_cw * buff_init_2(FILE *file2){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /*
        Initialisation du buffer 2
        Pré : file1, un pointeur de type 'FILE'
        Post : pointeur vers une structure 'buffer_cw'
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct buffer_cw *ptr2;
        ptr2 = malloc(sizeof(struct buffer_cw));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (ptr2 == NULL){return NULL;}
        ptr2->tab = malloc(2*N*sizeof(struct queue*));  //tableau de taille 2*N
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr2->size = 2*N;
        ptr2->len = 0;
        ptr2->head = 0;
        ptr2->tail = 0;
        ptr2->file2 = file2;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return ptr2;
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    struct buffer_rccw *buff_init_12(struct buffer_rc *ptr1,struct buffer_cw *ptr2){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /* 
        Initialisation d'une structure contenat des pointeurs vers les deux buffer pouvant être passée en argument à 'calculating'
        Pré : ptr1 un pointeur vers une structure 'buffer_rc' et ptr2 un pointeur vers une structure 'buffer_cw'
        Post : pointeur vers une structure 'buffer_rccw'
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct buffer_rccw *ptr3;
        ptr3 = malloc(sizeof(struct buffer_rccw));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (ptr3 == NULL){return NULL;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr3->struct1 = ptr1;       //pointeur vers le buffer 1
        ptr3->struct2 = ptr2;       //pointeur vers le buffer 2
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return ptr3;
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    int thread_create_join(struct buffer_rc *ptr1,struct buffer_cw *ptr2,struct buffer_rccw *ptr3){
        /*
        Création et point de rencontre des threads de lecture, calcul et écriture
        Pré : ptr1 un pointeur vers une structure buffer_rc, ptr2 un pointeur vers une strucure 'buffer_cw', ptr3 un pointeur vers une structure buffer_rccw
        Post : -1 en cas d'erreur, 0 sinon
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        pthread_t reader;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        pthread_t calculators[N];
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        pthread_t writer;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        err=pthread_create(&reader,NULL,&reading,ptr1); //le buffer 1 est passé en argument à 'reading'
        if(err != 0){return -1;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (int i = 0; i < N; i++)     //N threads de calcul
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            err=pthread_create(&calculators[i],NULL,&calculating,ptr3); //les deux buffers sont passés en argument à 'calculating'
            if(err != 0){return -1;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        err = pthread_create(&writer,NULL,&writing,ptr2); //le buffer 2 est passé en argument à 'writing'
        if(err != 0){return -1;}
    
        err = pthread_join(reader,NULL);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if(err != 0){return -1;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (int i = 0; i < N; i++)
    
            err = pthread_join(calculators[i],NULL);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            if(err != 0){return -1;}
    
        err = pthread_join(writer,NULL);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if(err != 0){return -1;}
    
        return 0;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void mut_sem_destroy(void){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /* 
        Destruction des sémaphores
        Pré : /
        Post : /
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        pthread_mutex_destroy(&mutex1);
        pthread_mutex_destroy(&mutex2);
        sem_destroy(&full1);
        sem_destroy(&full2);
        sem_destroy(&empty1);
        sem_destroy(&empty2);
    }
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    int run (char *input,char *output, int n_threads){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        /* 
        Fonction qui gère l'exécution du programme
        Pré : input et output des chaines de caractères, n_threads un entier
        Post : -1 en cas d'erreur, 0 sinon
        */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        N = n_threads;
    
        printf("Lancement du programme avec %d threads \n",N);
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        FILE *file1;
        FILE *file2;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
        file1 = fopen(input,"r");
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (file1 == NULL){
            printf("Sorry, file %s doesn't exist ): \n",input);
            return -1;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
        file2 = fopen(output,"w+");
        if (file2 == NULL){
            fclose(file1);
            return -1;
        }
        struct buffer_rc *ptr1 = buff_init_1(file1);
        struct buffer_cw *ptr2 = buff_init_2(file2);
        struct buffer_rccw *ptr3 = buff_init_12(ptr1,ptr2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        sem_1_initializer(ptr1);
        sem_2_initializer(ptr2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        int err;
        err = thread_create_join(ptr1,ptr2,ptr3);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        mut_sem_destroy();
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        fclose(file1);
        fclose(file2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        free(ptr1->tab);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        free(ptr1);
        free(ptr2);
        free(ptr3);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (err == -1){return -1;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return EXIT_SUCCESS;