Exemplo n.º 1
0
      static base_t my_exp2m1(const base_t &i)
	{
	  return my_exp2(i) - 1.0;
	}
Exemplo n.º 2
0
/*Questo è il main del processo principale, WATOR.
 * 1- Controllo di esistenza file
 * 2- Predispone i thread per la gestione corretta dei segnali
 * 3- Avvia i thread
 * 4- Aspetta che terminano il lavoro
 * */
int main (int argc, char *argv[]) {
    int n_tentativo;
    wat_proc_conf* x;
    /*Inizializzazione*/
    root_thread = pthread_self();
    /*Inizializza variabili globali di gestione dei segnali*/
    close_all = 0;
    sig_sigusr1 = 0;
    puoi_stampare = 0;
    count_worker = 0;
    puoi_procedere = 1;
    n_tentativo = 0;
    pthread_mutex_init(&set_critica, NULL);
    pthread_mutex_init(&set_skip, NULL);
    pthread_mutex_init(&lista_mux, NULL);
    pthread_mutex_init(&stampa_mux, NULL);
    pthread_cond_init(&lista_vuota, NULL);
    pthread_cond_init(&stanno_lavorando, NULL);
    pthread_cond_init(&stampa_pronta, NULL);
    pthread_cond_init(&stampa_effettuata, NULL);

    if ( mkdir("./tmp", S_IRWXU) ) {
        if(errno != EEXIST)
            perror("Errore Creazione Directory");
    }
    /*Rimuovo la socket se esiste, cioè se una precedente esecuzione è stata terminata male*/
    system("rm -f ./tmp/*");

    if( file_exist(SOCKNAME) ) {
        printf("Il file socket vecchio esiste ancora\n");
        if( remove(SOCKNAME) ) {
            perror("Non è stato possibile cancellare la vecchia socket");
            return 1;
        }
    }
    /*Gestione dei segnali
    * Vengono mascherati i segnali tipici di questo programma, cioè
    * SIGINT, SIGTERM e SIGUSR1
    * L'idea è quella di mascherare i segnali a tutti i thread tranne che
    * al gestore dei segnali, che si preoccuperà di gestire tutto.
    */
    sa.sa_handler=SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sigaddset(&sa.sa_mask, SIGINT);
    sigaddset(&sa.sa_mask, SIGUSR2);
    sigaddset(&sa.sa_mask, SIGTERM);
    sigaddset(&sa.sa_mask, SIGUSR1);
    /*Applico maschera a questo thread. La maschera poi viene ereditata dai figli*/
    pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL);
    /*Fine Gestione dei segnali*/

    /*Carico gli argomenti passati al programma*/
    x = valutazione_argomenti(argc, argv, NWORK_DEF, CHRON_DEF);
    if(x == NULL) {
        return 1;
    }

    /*Carico il nuovo pianeta*/
    if(!file_exist(x->file)) {
        errno = ENOENT;
        perror("File planet");
        return 1;
    }
    simulazione = new_wator(x->file);
    if(simulazione == NULL) {
        perror("Errore creazione nuova simulazione");
        return 1;
    }

    /*Se non sono stati passati argomenti, assegno quelli di default*/
    if( ( simulazione -> nwork = x->nwork ) == 0)
        simulazione -> nwork = NWORK_DEF;
    if( ( simulazione -> chronon = x->chron ) == 0)
        simulazione -> chronon = CHRON_DEF;
    if( x->dumpfile == NULL ) {
        strcpy(dumpfile,"stdout");
    }
    else {
        strcpy(dumpfile,x->dumpfile);
    }
    intervallo_di_stampa = (x->chron) ? x->chron : CHRON_DEF;

    free(x->file);
    free(x->dumpfile);
    free(x);

    /*Creo divisione della matrici per far lavorare i thread, funzione delegata dal dispatcher*/
    lista = split_matrice(simulazione->plan);
    /*Avvio Gestore Segnali*/
    n_tentativo=0;
    while( start_gestore_segnali() ) {
        if(n_tentativo < MAX_TRY) {
            sleep(my_exp2(n_tentativo));
            n_tentativo++;
        }
        else {
            perror("Errore creazione Thread Gestore Segnali");
            return 1;
        }
    }

    /*Avvio n worker*/
    n_tentativo=0;
    while ( (worker_thr_ids = start_nworker(simulazione->nwork)) == NULL ) {
        if(n_tentativo < MAX_TRY) {
            sleep(my_exp2(n_tentativo));
            n_tentativo++;
        }
        else {
            perror("Errore creazione Threads NWorker");
            return 1;
        }
    }
    /*Avvio visualizer*/
    n_tentativo=0;
    while ( (visualizer = start_visualizer(dumpfile)) == -1 ) {
        if(n_tentativo < MAX_TRY) {
            sleep(my_exp2(n_tentativo));
            n_tentativo++;
        }
        else {
            perror("Errore Start_Visualizer");
            return 1;
        }
    }

    /*Avvio thread collector*/
    n_tentativo=0;
    while( start_collector() ) {
        if(n_tentativo < MAX_TRY) {
            sleep(my_exp2(n_tentativo));
            n_tentativo++;
        }
        else {
            perror("Errore creazione Thread Collector");
            return 1;
        }
    }

    /*Avvio Thread Dispacer */
    n_tentativo=0;
    while( start_dispatcher() ) {
        if(n_tentativo < MAX_TRY) {
            sleep(my_exp2(n_tentativo));
            n_tentativo++;
        }
        else {
            perror("Errore Creazione Thread Dispatcher");
            return 1;
        }
    }

    /*Aspetto che i thread lanciati terminano
    */
    pthread_join(gestore_segnali_id, NULL);
    pthread_join(dispatcher_id, NULL);
    /*Procedura di recupero di collector se dormiva mentre tutti si chiudevano*/
    pthread_mutex_lock(&stampa_mux);
    puoi_stampare = TRUE;
    pthread_cond_broadcast(&stampa_pronta);
    pthread_mutex_unlock(&stampa_mux);
    pthread_join(collector_id, NULL);

    free_wator(simulazione);
    free(worker_thr_ids);

    if( remove(SOCKNAME) ) {
        perror("Non è stato possibile rimuovere il file SOCKNAME");
        return 1;
    };

    pthread_mutex_destroy(&set_critica);
    pthread_mutex_destroy(&set_skip);
    pthread_mutex_destroy(&lista_mux);
    pthread_mutex_destroy(&stampa_mux);
    pthread_cond_destroy(&lista_vuota);
    pthread_cond_destroy(&stanno_lavorando);
    pthread_cond_destroy(&stampa_pronta);
    pthread_cond_destroy(&stampa_effettuata);

    return 0;
}