Example #1
0
/* Main */
int main (int argc, char **argv)
{
    unsigned long long perf;
    tsp_path_t path;
    tsp_path_t sol;
    int sol_len;
    long long int cuts = 0;
    struct tsp_queue q;
    struct timespec t1, t2;

    /* lire les arguments */
    int opt;
    while ((opt = getopt(argc, argv, "s")) != -1) {
        switch (opt) {
            case 's':
                affiche_sol = true;
                break;
            default:
                usage(argv[0]);
                break;
        }
    }

    if (optind != argc-3)
        usage(argv[0]);

    nb_towns = atoi(argv[optind]);
    myseed = atol(argv[optind+1]);
    nb_threads = atoi(argv[optind+2]);
    assert(nb_towns > 0);
    assert(nb_threads > 0);

    minimum = INT_MAX;

    /* generer la carte et la matrice de distance */
    fprintf (stderr, "ncities = %3d\n", nb_towns);
    genmap ();

    init_queue (&q);

    clock_gettime (CLOCK_REALTIME, &t1);

    memset (path, -1, MAX_TOWNS * sizeof (int));
    path[0] = 0;

    /* mettre les travaux dans la file d'attente */
    generate_tsp_jobs (&q, 1, 0, path, &cuts, sol, & sol_len, 3);
    no_more_jobs (&q);

    /* calculer chacun des travaux */
    tsp_path_t solution;
    memset (solution, -1, MAX_TOWNS * sizeof (int));
    solution[0] = 0;
    ThreadCell* list = NULL;
    ThreadCell* cur = NULL;

    for (int i = 0; i < nb_threads; i++) {
        ThreadCell* cell = (ThreadCell*) malloc(sizeof(ThreadCell));
        cell->next = NULL;
        WorkerArgs* args = (WorkerArgs*) malloc(sizeof(WorkerArgs));
        args->q = &q;
        memcpy(args->solution, solution, sizeof(tsp_path_t));
        args->cuts = &cuts;
        memcpy(args->sol, sol, sizeof(tsp_path_t));
        args->sol_len = &sol_len;
        pthread_create(&(cell->tid), NULL, tsp_worker, (void*) args);
        if (!list) {
            list = cell;
            cur = list;
        } else {
            cur->next = cell;
            cur = cur->next;
        }
        
    }
    
    void * status;
    while (list != NULL) {
        pthread_join(list->tid, &status);
        if (status == PTHREAD_CANCELED) {
            printf("Thread cancelled");
            exit(EXIT_FAILURE);
        }
        ThreadCell* tmp = list;
        list = list->next;
        free(tmp);
    }
    
    clock_gettime (CLOCK_REALTIME, &t2);

    if (affiche_sol)
        print_solution_svg (sol, sol_len);

    perf = TIME_DIFF (t1,t2);
    printf("<!-- # = %d seed = %ld len = %d threads = %d time = %lld.%03lld ms ( %lld coupures ) -->\n",
            nb_towns, myseed, sol_len, nb_threads,
            perf/1000000ll, perf%1000000ll, cuts);
    freemap();
    return 0 ;
}
Example #2
0
int main (int argc, char **argv)
{
    unsigned long long perf;
    tsp_path_t path;
    struct tsp_queue q;
    struct timespec t1, t2;
	

    /* lire les arguments */
    int opt;
    while ((opt = getopt(argc, argv, "s")) != -1) {
      switch (opt) {
      case 's':
	affiche_sol = true;
	break;
      default:
	usage(argv[0]);
	break;
      }
    }

    if (optind != argc-3)
      usage(argv[0]);

    nb_towns = atoi(argv[optind]);
    myseed = atol(argv[optind+1]);
    nb_threads = atoi(argv[optind+2]);
    assert(nb_towns > 0);
    assert(nb_threads > 0);
   
    minimum = INT_MAX;
      
    /* generer la carte et la matrice de distance */
    fprintf (stderr, "ncities = %3d\n", nb_towns);
    genmap ();

    init_queue (&q);

    clock_gettime (CLOCK_REALTIME, &t1);
	
	/* on vide le chemin 'path' : on met des -1 dans toutes les cases */
    memset (path, -1, MAX_TOWNS * sizeof (int));
	/* on définit la première ville comme étant 0 */
    path[0] = 0;

    /* On met des travaux dans la file d'attente q */
    generate_tsp_jobs (&q, 1, 0, path, &cuts, sol, & sol_len, 3);
    no_more_jobs (&q);
   
	/* on vide le chemin 'solution' : on met des -1 dans toutes les cases */
	/* puis on définit la première ville comme étant 0 */
    tsp_path_t solution;
    memset (solution, -1, MAX_TOWNS * sizeof (int));
    solution[0] = 0;

	/* allocation du tableau d'informations sur les threads */
    tab_threads = malloc(nb_threads*sizeof(Cell));
	memset(tab_threads, 0, nb_threads*sizeof(int));

	/* initialisation du mutex*/
	pthread_mutex_init(&mutex, NULL);

	int i;

	/* on place tous les threads dans l'état 'non-occupé' */
	for(i=0; i<nb_threads; i++){
		tab_threads[i].occupe = 0;
    }

	/* Tant que la file de jobs n'est pas vide on sort un job et on l'execute avec tsp */
    while (!empty_queue (&q)) {
        int hops = 0, len = 0;
		/* on récupère un job dans la file d'atente des jobs */
        get_job (&q, solution, &hops, &len);
        
        i = 0;
		/* on boucle tant qu'on n'a pas trouvé de thread pour effectuer le job */
        while (1){
			/* si le thread i n'est pas occupé alors on va l'utiliser pour effectuer le job */
            if(!tab_threads[i].occupe){
                
				/* on place le thread i en statut 'occupé' */
                tab_threads[i].occupe = 1;

				/* on crée une structure arguments qui va recevoir les arguments de tsp */
                struct arg_struct arguments;

				arguments.hops = hops;
				arguments.len = len;
				memcpy(arguments.path, solution, nb_towns * sizeof (int));

				/* tsp est récursive et on a besoin de savoir quand le thread a terminé le job afin de le mettre en 'non-occupé' */
				/* On introduit donc un entier qui est 1 si le tsp appelé est celui du père et 0 si c'est dans les fils */
                arguments.pere = 1; 

				/* lancement du thread sur tsp avec les bons arguments*/
                pthread_create (&tab_threads[i].thread, NULL, tsp, (void*)&arguments);
                break;
            }
			/* sinon on va regarder si le suivant%nb_threads est occupé */
            i = (i+1)%nb_threads;
        }
    }

    i = 0;
	/* on attend la fin de tous les threads avant de continuer */
    while(1){
        pthread_join(tab_threads[i].thread, NULL);
        i++;
        if (i == nb_threads) break;
    }
    
    clock_gettime (CLOCK_REALTIME, &t2);

    if (affiche_sol)
      print_solution_svg (sol, sol_len);

    perf = TIME_DIFF (t1,t2);
    printf("<!-- # = %d seed = %ld len = %d threads = %d time = %lld.%03lld ms ( %lld coupures ) -->\n",
	   nb_towns, myseed, sol_len, nb_threads,
	   perf/1000000ll, perf%1000000ll, cuts);

    return 0 ;
}
int main (int argc, char **argv)
{
    unsigned long long perf;
    tsp_path_t path;
    tsp_path_t sol;
    int sol_len;
    long long int cuts = 0;
    struct tsp_queue q;
    struct timespec t1, t2;

    /* lire les arguments */
    int opt;
    while ((opt = getopt(argc, argv, "s")) != -1) {
      switch (opt) {
      case 's':
	affiche_sol = true;
	break;
      default:
	usage(argv[0]);
	break;
      }
    }

    if (optind != argc-3)
      usage(argv[0]);

    nb_towns = atoi(argv[optind]);
    myseed = atol(argv[optind+1]);
    nb_threads = atoi(argv[optind+2]);
    assert(nb_towns > 0);
    assert(nb_threads > 0);
   
    minimum = INT_MAX;
      
    /* generer la carte et la matrice de distance */
    fprintf (stderr, "ncities = %3d\n", nb_towns);
    genmap ();

    init_queue (&q);

    clock_gettime (CLOCK_REALTIME, &t1);

    memset (path, -1, MAX_TOWNS * sizeof (int));
    path[0] = 0;

    /* mettre les travaux dans la file d'attente */
    generate_tsp_jobs (&q, 1, 0, path, &cuts, sol, & sol_len, 3);
    no_more_jobs (&q);
   
    /* calculer chacun des travaux */
    tsp_path_t solution;
    memset (solution, -1, MAX_TOWNS * sizeof (int));
    solution[0] = 0;
    while (!empty_queue (&q)) {
        int hops = 0, len = 0;
        get_job (&q, solution, &hops, &len);
        tsp (hops, len, solution, &cuts, sol, &sol_len);
    }
    
    clock_gettime (CLOCK_REALTIME, &t2);

    if (affiche_sol)
      print_solution_svg (sol, sol_len);

    perf = TIME_DIFF (t1,t2);
    printf("<!-- # = %d seed = %ld len = %d threads = %d time = %lld.%03lld ms ( %lld coupures ) -->\n",
	   nb_towns, myseed, sol_len, nb_threads,
	   perf/1000000ll, perf%1000000ll, cuts);

    return 0 ;
}