void * average() { /* Récupération des variables pour la condition de fin */ pthread_mutex_lock(&files); pthread_mutex_lock(&newfract); pthread_mutex_lock(&finished); int flag = flagFiles; int nread = readFract; int nfinished = finishedFract; pthread_mutex_unlock(&files); pthread_mutex_unlock(&newfract); pthread_mutex_unlock(&finished); struct fractal *bestAv = fractal_new("empty", 1, 1, 0.0, 0.0); //Variable où stocker la meilleure fractale while (!flag || nread != nfinished) { //Tant qu'il y a des fichiers à lire ou que le nombre de fractales créées est différent du nombre de fracales terminées sem_wait(&full2); //On attend qu'il y ait quelque chose dans le buffer pthread_mutex_lock(&mutex2); //On lock struct fractal *test = stack_pop(&buffer2); //On prend la fractale; if (fractal_get_av(test) > fractal_get_av(bestAv)) { //Si la fractale est meilleure que celle précédement en mémoire fractal_free(bestAv); bestAv = test; } else { fractal_free(test); } pthread_mutex_unlock(&mutex2); sem_post(&empty2); /* Update des variables pour la condition de fin */ pthread_mutex_lock(&files); pthread_mutex_lock(&newfract); pthread_mutex_lock(&finished); finishedFract++; //Une fracatle supplémentaire est terminée flag = flagFiles; nread = readFract; nfinished = finishedFract; pthread_mutex_unlock(&files); pthread_mutex_unlock(&newfract); pthread_mutex_unlock(&finished); } pthread_exit((void *) bestAv); //Renvoie la meilleure fractale }
void test_libfractal_get_set_value() { fractal_t *ptr = fractal_new(name, 10, 10, a, b); int w = fractal_get_width(ptr); int h = fractal_get_height(ptr); int x = 0; int y = 0; for ( y = 0; y < h ; y++) { for( x = 0; x < w ; x++) { fractal_set_value(ptr, x, y, x+y*10); } } for ( y = 0; y < h ; y++) { for( x = 0; x < w ; x++) { CU_ASSERT_EQUAL(fractal_get_value(ptr, x, y), x+y*10); } } fractal_free(ptr); }
fractal_t *fractal_new(const char *name, int width, int height, double a, double b) { fractal_t *f_new = (fractal_t *) malloc(sizeof(fractal_t *)); check_mem(f_new); int n = 65; strncpy(f_new->name, name, (size_t) n); f_new->value = (int *) malloc(height * width * sizeof(int)); check_mem(f_new); f_new->w = width; f_new->h = height; f_new->a = a; f_new->b = b; return f_new; error: if(f_new) free(f_new); if(f_new->value) fractal_free(f_new->value); exit(EXIT_FAILURE); }
/* * Fonction principale du programme */ int main(int argc, char const *argv[]) { printf("Bonjour et bienvenue dans ce programme de création de fracatles\n"); //Bonjour /* Lecture des arguments */ if (argc < 3) { //Il faut au moins 3 arguments (le nom de base, un fichier d'entrée et un de sortie) fprintf(stderr, "Il n'y a pas assez d'arguments donnés, vous devez au moins donner un fichier contenant les fractales et un fichier de sortie!\n"); exit(EXIT_FAILURE); } char const *arg = argv[nbrArg]; if (strcmp(arg, "-d") == 0) { //Si on trouve le -d, mettre le flag à 1 flagDetail = 1; nbrArg++; //Un argument de lu, passons au suivant printf("Vous avez choisi l'option -d\n"); } else { flagDetail = 0; } arg = argv[nbrArg]; if (strcmp(arg, "--maxthreads") == 0) { //Chercher maxthreads nbrArg++; //On va un argument plus loin pour trouver le nombre int nbr = atoi(argv[nbrArg]); //Récupérer le nombre maxThreads = nbr; //Le stocker nbrArg++; //Passer à l'argument suivant printf("Vous avez demandé %i threads de calcul\n", maxThreads); arg = argv[nbrArg]; //Permet de switcher les arguments mais moche if (strcmp(arg, "-d") == 0) { //Si on trouve le -d, mettre le flag à 1 flagDetail = 1; nbrArg++; printf("Vous avez choisi l'option -d\n"); } } else { printf("Vous n'avez pas précisé de nombre de threads de calcul, nombre par défaut : 1\n"); maxThreads = 1; } /* Initialisation des buffers, mutex et semaphores */ initFirst(); initSecond(); initThird(); /* Lancement des producteurs */ pthread_t threadP[argc-nbrArg-1]; //Stockage des threads de production int nthreadP = 0; //Nombre de threads de production while (nbrArg < argc-1) { //Tant qu'on a des arguments à lire (ici, ce sont des fichiers + s'arrêter un avant la fin pour l'output) char const *fichier = argv[nbrArg]; if (strcmp(fichier, "-") == 0) //S'il faut lire l'entrée standart lectureSTDin(); pthread_t th = NULL; threadP[nthreadP] = th; int res = pthread_create(&threadP[nthreadP], NULL, *producer, (void *) fichier); //Création d'un producteur if (res != 0) fprintf(stderr, "Problème à la création d'un producteur pour le fichier %s\n", fichier); nthreadP++; nbrArg++; } /* Lancement des consommateurs */ for(int i = 0; i < maxThreads; i++){ pthread_t th = NULL; int res = pthread_create(&th, NULL, *consumer, NULL); //Création d'un consommateur if (res != 0) fprintf(stderr, "Problème à la création du consumer n°%d\n", i); } /* Thread de moyenne */ pthread_t moyenne = NULL; int res = pthread_create(&moyenne, NULL, *average, NULL); //Création du thread de moyenne if (res != 0) fprintf(stderr, "Problème à la création du thread de moyenne\n"); /* Jointure des threads de production, fichier lu entièrement */ for (int i = 0; i < nthreadP; i++) pthread_join(threadP[i], NULL); pthread_mutex_lock(&files); flagFiles = 1; //Les fichiers sont tous lus pthread_mutex_unlock(&files); /* Jointure du thread de moyenne */ void * ret = NULL; pthread_join(moyenne, &ret); struct fractal * bestAv = (struct fractal *) ret; //Récupère la meilleure fractale /* Libération des buffers */ free_list(buffer1); free_list(buffer2); write_bitmap_sdl(bestAv, argv[nbrArg]); //Écriture du fichier printf("Fichier %s écrit avec : %s\n", argv[nbrArg], fractal_get_name(bestAv)); remove(fractal_get_name(bestAv)); //Supression du fichier doublon fractal_free(bestAv); return EXIT_SUCCESS; }
void test_libfractal_get_b() { fractal_t *ptr = fractal_new(name, width, height, a, 42.0); CU_ASSERT_EQUAL(fractal_get_b(ptr), 42.0); fractal_free(ptr); }
void test_libfractal_get_height() { fractal_t *ptr = fractal_new(name, width, 42, a, b); CU_ASSERT_EQUAL(fractal_get_height(ptr), 42); fractal_free(ptr); }
void test_libfractal_get_name() { fractal_t *ptr = fractal_new("CUnit", width, height, a, b); CU_ASSERT_EQUAL(fractal_get_name(ptr), "CUnit"); fractal_free(ptr); }
void test_libfractal_ptr_value_not_null() { fractal_t *ptr = fractal_new(name, width, height, a, b); CU_ASSERT_PTR_NOT_NULL(ptr->value); fractal_free(ptr); }