Skip to content
Extraits de code Groupes Projets
run.c 10 ko
Newer Older
  • Learn to ignore specific revisions
  • Laurent Paucot's avatar
    Laurent Paucot a validé
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    #include <unistd.h>
    
    #include <pthread.h>
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    #include <semaphore.h>
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    int N; 
    
    //travailler avec des linkendList
    typedef struct node{ 
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        unsigned long long value;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct node *next;
    }node_t;
    
    
    typedef struct queue{ 
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct node *tail;
        int size;
    
        int final;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }queue_t;
    
    struct buffer_rc{
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        char **tab;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        int size;       
        int len;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        int head;
        int tail;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        int stop;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        FILE *file1;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    };
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    struct buffer_cw
    {
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        queue_t **tab;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        int size;       
        int len;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        int head;
        int tail;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        int stop;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        FILE *file2;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    struct buffer_rccw{
        struct buffer_rc *struct1;
        struct buffer_cw *struct2; 
    };
    
    /* sémaphore est une structure de donné qui contient :
        *un entier qui stocke la valeur, positive ou nulle du sémaphore.
        *une queue qui contient les pointeurs vers les threads
    */
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    pthread_mutex_t mutex1;
    sem_t empty1;
    sem_t full1;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    pthread_mutex_t mutex2;
    sem_t empty2;
    sem_t full2;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void put_in_buffer_1(char *c, struct buffer_rc *ptr){ //ajouter un element dans le buffer 1
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr->tab[ptr->head] = malloc(sizeof(c)); // on stoxke de espace 
        //ptr->tab[ptr->head] = c;
        strcpy(ptr->tab[ptr->head],c); //copie
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        
        ptr->len++; 
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr->head = (ptr->head + 1)%ptr->size; //chaque fois qu'un élément est ajouté, 
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        //on augmente le pointeur de 1 mais l'espace du buffer est de size donc faire un modulo
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    char *get_from_buffer_1(struct buffer_rc *ptr){ // chercher dans le buffer 1
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        char *result;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        result = ptr->tab[ptr->tail]; // donne un valeur a result
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        //free(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--; //diminue l'espace occupé dans le buffer
    
    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é
    }
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void put_in_buffer_2(struct queue *ptr, struct buffer_cw *buf){ //ajouter un element dans le buffer 2
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->tab[buf->head] = malloc(sizeof(*ptr));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->tab[buf->head] = ptr;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->len++; //augmente l'espace occupé dans le buffer
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->head = (buf->head + 1)%buf->size;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    queue_t *get_from_buffer_2(struct buffer_cw *buf){ // trouver un element
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct queue *result;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        result = buf->tab[buf->tail]; //donne une valeur a result
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->tab[buf->tail] = NULL;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        buf->len--; //diminue l'espace occupé par le buffer
        buf->tail = (buf->tail + 1)%buf->size;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return result;
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    int is_div(unsigned long long number, unsigned long long i) { // Vérifie si i est un diviseur de number.
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return (number % i == 0) ; // renvoie 0 si le nombre n'est pas divisible par i et 1 si il est divisible
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    int is_prime(unsigned long long number) { // Vérifie si number est un nombre premier. Return 1 si il est premier, 0 sinon
    
    Corentin Zgajewski Delforge's avatar
    Corentin Zgajewski Delforge a validé
        if (number != 2) {
            if (number  % 2 == 0) {
                return 0 ;
            }
        }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (unsigned long long i = 3 ; i <= (number/2); i = i + 2) { //regarde les differents nombres pouvant etre diviser number
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            if (is_div(number,i) != 0) { // si i peut diviser number
                return 0 ; //renvoi 0 => FAUX
            }
        }
        return 1 ; //sinon => VRAI
    }
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void enqueue(queue_t* q, unsigned long long val){ 
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct node new_node;
        new_node.value = val;
        new_node.next = malloc(sizeof(node_t));
    
    
    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){
            free(ptr);
            return;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        *ptr = new_node;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
        if (q->size == 0)
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            *q->tail = *ptr;
            *ptr->next = *ptr;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        else{
            *ptr->next = *q->tail->next;
            *q->tail->next = *ptr;
        }
        q->size++;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        
        //free(ptr->next);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        free(ptr);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    }
    
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    queue_t* prime_divs(unsigned long long number){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        struct queue new_queue;
        new_queue.size = 0;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        new_queue.final = 0;
    
        new_queue.tail = malloc(sizeof(node_t));
        if(new_queue.tail==NULL){return NULL;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
        struct queue *ptr;
        ptr = malloc(sizeof(queue_t));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (ptr == NULL){
            free(new_queue.tail);
            free(ptr);
            return NULL;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        *ptr = new_queue;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (unsigned long long 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);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        enqueue(ptr,number);
    
    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é
    
        struct buffer_cw *param1 = (struct buffer_cw *) param;
    
        int stop = 0;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        
    
        while(param1->stop == 0){            
           
    
    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);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pthread_mutex_unlock(&mutex2);
    
            sem_post(&empty2); 
    
            if (pr_divs->final == 1)
            {   
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                
    
                if (stop == N-1){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                    for (int i = 0; i < param1->size; i++)
                    {
                        param1->tab[i] = NULL;
                    }
                    free(param1->tab);
                    free(pr_divs);
    
                    return NULL;
                }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                free(pr_divs);
    
                stop++;
            }
            else{
                FILE *file2 = param1->file2;   
    
                struct node *current;
                current = malloc(sizeof(node_t));
                if (current == NULL){return NULL;}
                *current = *pr_divs->tail;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                current = current->next;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                fprintf(file2,"%llu",current->value);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                current = current->next;
    
                for (int i = 1; i < pr_divs->size; i++)
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                    fprintf(file2," %llu",current->value);
    
                    current = current->next;
                }
                fputc('\n',file2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
                
                //free(current);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
           
    
    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 *calculating(void *param){
    
    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(buffer_1->stop == 0){  
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
    
    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);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pthread_mutex_unlock(&mutex1);
    
            sem_post(&empty1);
    
            if (strcmp("stop",chaine) == 0)
            {   
                struct queue *final;
                final = malloc(sizeof(queue_t));
                if (final == NULL){return NULL;}
    
                final->final = 1;
    
                sem_wait(&empty2);
                pthread_mutex_lock(&mutex2);
                put_in_buffer_2(final,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é
    
            struct queue *pr_divs;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pr_divs = malloc(sizeof(queue_t));
            if (pr_divs == NULL){return NULL;}
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pr_divs = prime_divs(strtoll(chaine,NULL,0));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            
    
    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);    
    
    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é
        return NULL;
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void *reading (void *param){
    
    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é
    
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        FILE *input;
        input = param1->file1;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        while (fgets(chaine,30,input) != NULL){
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            
    
    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);            //put each line in the 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);            //put each stop line in the buffer #1
    
            
            pthread_mutex_unlock(&mutex1);
            sem_post(&full1);
        }
        
    
    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é
    
    
    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é
        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){
    
    
    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){
    
    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*));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr1->size = 2*N;
        ptr1->len = 0;
        ptr1->head = 0;
        ptr1->tail = 0;
        ptr1->stop = 0;
        ptr1->file1 = file1;
        
        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é
        struct buffer_cw *ptr2;
        ptr2 = malloc(sizeof(struct buffer_cw));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        if (ptr2 == NULL){
    
    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é
        ptr2->tab = malloc(2*N*sizeof(struct queue*));
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        ptr2->size = 2*N;
        ptr2->len = 0;
        ptr2->head = 0;
        ptr2->tail = 0;
        ptr2->stop = 0;
        ptr2->file2 = file2;
        
        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é
        struct buffer_rccw buffer_12;
        buffer_12.struct1 = ptr1;
        buffer_12.struct2 = ptr2;
    
    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 = buffer_12;
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return ptr3;
    }
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    void thread_create_join(struct buffer_rc *ptr1,struct buffer_cw *ptr2,struct buffer_rccw *ptr3){
    
    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é
        pthread_create(&reader,NULL,&reading,ptr1);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (int i = 0; i < N; i++)
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
            pthread_create(&calculators[i],NULL,&calculating,ptr3);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        pthread_create(&writer,NULL,&writing,ptr2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        pthread_join(reader,NULL);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        for (int i = 0; i < N; i++)
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        {
            pthread_join(calculators[i],NULL);
        }
        pthread_join(writer,NULL);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    int run (char *input,char *output, int n_threads){
    
        N = n_threads;
        
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
        FILE *file1 = NULL;
        FILE *file2 = NULL;
    
        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é
        
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
    
        sem_1_initializer(ptr1);
        sem_2_initializer(ptr2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        thread_create_join(ptr1,ptr2,ptr3);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        fclose(file1);
        fclose(file2);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        free(ptr1);
        free(ptr2);
        free(ptr3);
    
    Laurent Paucot's avatar
    Laurent Paucot a validé
        return EXIT_SUCCESS;