int print_planet (FILE* f, planet_t* p){ int i,j; /** errore de file non valido */ if ( ! f ) return -1; /* stampo le indicazioni riga colonna */ fprintf (f, "%d\n%d\n", p->nrow, p->ncol); for (i=0; i<p->nrow; i++) for( j=0; j<p->ncol; j++ ) /* per ogni cella stampo il carattere ed uno spazio o il carattere ed un endline */ #ifndef COLOR_DEBUG if ( ! fprintf(f, ( j==p->ncol-1 ) ? "%c\n" : "%c ", cell_to_char( p->w[i][j] )) ) return -1; #else { if ( p->w[i][j] == WATER ) printf ( "\x1b[34m" "W" "\x1b[0m" ); if ( p->w[i][j] == SHARK ) printf ( "\x1b[31m" "S" "\x1b[0m" ); if ( p->w[i][j] == FISH ) printf ( "\x1b[32m" "F" "\x1b[0m" ); printf ( (j == p->ncol -1) ? "\n" : " " ); } #endif #ifndef DEBUG return 0; #endif }
static void* collector (void* arg){ int fd_skt, i, j; struct sockaddr_un sockAdd; char string[10]; planet_t* p; strncpy(sockAdd.sun_path, SOCKNAME, UNIX_PATH_MAX); sockAdd.sun_family=AF_UNIX; fd_skt = socket(AF_UNIX, SOCK_STREAM, 0); if(fd_skt == -1){ perror("Errore socket client"); } /*Prova a connetterti. Se la socket non esiste, aspetta 0,25 secondi e ritenta*/ while( connect(fd_skt, (struct sockaddr*) &sockAdd, sizeof(sockAdd)) == -1){ if( errno == ENOENT ){ usleep(250000); } else{ perror("Errore connessione socket client"); close_all = TRUE; /*Termina l'intero processo*/ return NULL; } } p = simulazione->plan; /*Inizio ciclo iterativo del thread*/ while( termine_elaborazione == FALSE ){ pthread_mutex_lock(&stampa_mux); /*Si mette in attesa finchè il dispatcher non comunica la possibilità di stampare*/ while(!puoi_stampare){ pthread_cond_wait(&stampa_pronta, &stampa_mux); } pthread_mutex_unlock(&stampa_mux); /*Scrive un carattere TOKEN che fa capire al visualizer che è terminata una matrice e ne sta per iniziare una nuova*/ write(fd_skt, TOKEN, 1); sprintf(string, "%d\n", p->nrow); write(fd_skt, string, strlen(string)); sprintf(string, "%d\n", p->ncol); write(fd_skt, string, strlen(string)); for(i=0;i<p->nrow; i++){ for(j=0; j<p->ncol-1;j++){ sprintf(string, "%c ", cell_to_char((p->w)[i][j])); write(fd_skt, string, strlen(string)); } sprintf(string, "%c\n", cell_to_char((p->w)[i][j])); write(fd_skt, string, strlen(string)); } /*Comunica che è stata effettuata la stampa e quindi il dispatcher può * nuovamente modificare la matrice*/ pthread_mutex_lock(&stampa_mux); puoi_stampare = FALSE; puoi_procedere = TRUE; pthread_cond_signal(&stampa_effettuata); pthread_mutex_unlock(&stampa_mux); } close(fd_skt); return NULL; }
void* coll(void* _c) { int i; int j; collector* c; int fd_skt; char buf[N]; struct sockaddr_un sa; int w; int timer; char *riga; char scelta[2]; int r; FILE* wa_check; sigset_t set; sigfillset(&set); /* Maschero tutti i segnali in modo che solo il processo wator li gestisca */ if(pthread_sigmask(SIG_SETMASK,&set,NULL) < 0) { exit(1); } riga = (char*) malloc(((wator->plan->ncol)+1)*sizeof(char)); strncpy(sa.sun_path, SOCKNAME,UNIX_PATH_MAX); sa.sun_family=AF_UNIX; c = (collector*) _c; /* for(i=0;i<(c->nwork); ++i) { pthread_join(c->tid[i], NULL); } */ timer = 0; while(1) { /* sleep(1); */ pthread_mutex_lock(&state_lock); while(state != 3) { pthread_cond_wait(&c_cond, &state_lock); } pthread_mutex_unlock(&state_lock); if(su) /* Se "su" è settata allora devo fare una scrittura sul file wator.check */ { if( (wa_check = fopen("wator.check", "w")) == NULL) return (void*) 1; print_planet(wa_check, wator->plan); fclose(wa_check); su = 0; } fd_skt=socket(AF_UNIX,SOCK_STREAM,0); while (connect(fd_skt,(struct sockaddr*)&sa,sizeof(sa)) == -1 ) { if ( errno == ENOENT ) { fprintf(stderr, "ENOENT\n" ); sleep(1); } /*sock non esiste*/ else sleep(1); } /* * PROTOCOLLO: * Il thread collector invia un valore diverso sulla socket a seconda che * la variabile "sit" (legata a SIGINT e SIGTERM) sia stata settata. Nel * caso "sit" sia uguale a 1 invio 1 al visualizer e aspetto la sua * risposta. Se invece "sit" è uguale a 0 allora è tutto ok, dunque * viene mandato 0 sulla socket e subito dopo viene mandata anche la * matrice. Ogni volta che collector invia qualcosa, aspetta un ack da * parte del visualizer per proseguire. */ if(sit) { scelta[0] = '1'; scelta[1] = '\0'; w = write(fd_skt,scelta, strlen(scelta)+1); while( (r = read(fd_skt, buf, strlen(scelta)+1)) != 2); free(riga); last = 1; pthread_mutex_lock(&state_lock); state = 1; pthread_mutex_unlock(&state_lock); pthread_cond_broadcast(&d_cond); //pthread_cond_broadcast(&w_cond); return (void*) 0; } else { if( (timer%(c->chronon)) == 0) /* Se è il chronon giusto, invio sulla socket */ { scelta[0] = '0'; scelta[1] = '\0'; w = write(fd_skt,scelta, strlen(scelta)+1); while( (r = read(fd_skt, buf, strlen(scelta)+1)) != 2); for(i=0; i<(wator->plan->nrow); ++i) { for(j=0; j<(wator->plan->ncol); ++j) { riga[j] = cell_to_char(wator->plan->w[i][j]); } riga[j] = '\0'; if((w = write(fd_skt,riga, strlen(riga)+1) != -1)); while( (r = read(fd_skt, buf, sizeof(scelta))) == -1); } } } close(fd_skt); ++timer; pthread_mutex_lock(&state_lock); state = 1; pthread_cond_broadcast(&d_cond); pthread_mutex_unlock(&state_lock); } return (void*) 0; }
/** * * questo programma testa tutte le funzioni finora implementate * * esegue un test alla volta passando il risultato alla funzione print_result * **/ int main () { planet_t *pl; wator_t *wt; cell_t **copia; cell_t c; int k,l,p,g,n; FILE *f1, *f2; mtrace(); print_result ( cell_to_char(WATER) == 'W' , "cell_to_char(WATER)" ); print_result ( cell_to_char(FISH) == 'F' , "cell_to_char(FISH)" ); print_result ( cell_to_char(SHARK) == 'S' , "cell_to_char(SHARK)" ); print_result ( char_to_cell('W') == WATER , "char_to_cell('W')" ); print_result ( char_to_cell('F') == FISH , "char_to_cell('F')" ); print_result ( char_to_cell('S') == SHARK , "char_to_cell('S')" ); print_result ( char_to_cell('P') == -1 , "char_to_cell('P')" ); print_result ( char_to_cell( cell_to_char (WATER) ) == WATER , "char_to_cell( cell_to_char (WATER) )" ); print_result ( cell_to_char( char_to_cell ('F') ) == 'F' , "cell_to_char( char_to_cell ('F') )" ); test_matrice_generica (10,40); test_matrice_generica (1000,40000); pl=new_planet (10,10); print_result ( ( pl!=NULL && pl->nrow==10 && pl->ncol==10 ) || errno==ENOMEM, "new_planet (10,10)" ); free_planet (pl); contatore_pesci=contatore_squali=0; print_result ( controlla_formato_e_conta_squali_e_pesci ('W', ' ', 0, &c ) && c == WATER , "controlla_formato_e_conta_squali_e_pesci ('W', ' ', 0, &c )" ); print_result ( controlla_formato_e_conta_squali_e_pesci ('F', ' ', 0, &c ) && c == FISH && contatore_pesci==1 , "controlla_formato_e_conta_squali_e_pesci ('F', ' ', 0, &c )" ); print_result ( controlla_formato_e_conta_squali_e_pesci ('S', '\n', 1, &c ) && c == SHARK && contatore_squali==1 , "controlla_formato_e_conta_squali_e_pesci ('S', '\\n', 1, &c )" ); print_result ( ! controlla_formato_e_conta_squali_e_pesci ('M', '\n', 1, &c ), "controlla_formato_e_conta_squali_e_pesci ('M', '\\n', 1, &c )" ); print_result ( ! controlla_formato_e_conta_squali_e_pesci ('W', '\n', 0, &c ), "controlla_formato_e_conta_squali_e_pesci ('W', '\\n', 0, &c )" ); print_result ( ! controlla_formato_e_conta_squali_e_pesci ('W', 'a', 0, &c ), "controlla_formato_e_conta_squali_e_pesci ('W', 'a', 0, &c )" ); print_result ( test_load_store ("custom_test/planet1.dat", 1), "test_load_store(\"custom_test/planet1.dat\")" ); print_result ( test_load_store ("custom_test/planet2.dat", 1), "test_load_store(\"custom_test/planet2.dat\")" ); print_result ( test_load_store ("custom_test/planet3.dat", 0), "test_load_store(\"custom_test/planet3.dat\")" ); print_result ( test_load_store ("custom_test/planet4.dat", 0), "test_load_store(\"custom_test/planet4.dat\")" ); print_result ( test_load_store ("custom_test/planet5.dat", 0), "test_load_store(\"custom_test/planet5.dat\")" ); wt = malloc ( sizeof(wator_t) ); wt->plan = NULL; system ("rm -f wator.conf"); print_result ( read_wator_conf (wt) == -1, "read_wator_conf without wator.conf" ); system ("cp custom_test/wator.conf.1 wator.conf"); print_result ( read_wator_conf (wt) == 1 && wt->sd == 100 && wt->sb == 20 && wt->fb == 15 , "read_wator_conf wator.conf.1" ); system ("cp custom_test/wator.conf.2 wator.conf"); print_result ( ! read_wator_conf(wt) && errno == ERANGE , "read_wator_conf wator.conf.2" ); system ("cp custom_test/wator.conf.3 wator.conf"); print_result ( ! read_wator_conf(wt) && errno == ERANGE , "read_wator_conf wator.conf.3" ); system ("cp custom_test/wator.conf.4 wator.conf"); print_result ( ! read_wator_conf(wt) && errno == ERANGE , "read_wator_conf wator.conf.4" ); system ("cp custom_test/wator.conf.5 wator.conf"); print_result ( ! read_wator_conf(wt) && errno == ERANGE , "read_wator_conf wator.conf.5" ); system ("cp custom_test/wator.conf.6 wator.conf"); print_result ( ! read_wator_conf(wt) && errno == ERANGE , "read_wator_conf wator.conf.6" ); system ("cp custom_test/wator.conf.7 wator.conf"); print_result ( ! read_wator_conf(wt) && errno == ERANGE , "read_wator_conf wator.conf.7" ); system ("cp custom_test/wator.conf.8 wator.conf"); print_result ( ! read_wator_conf(wt) && errno == ERANGE , "read_wator_conf wator.conf.8" ); free_wator (wt); system ("cp custom_test/wator.conf.1 wator.conf"); wt=new_wator ("custom_test/planet1.dat"); print_result ( wt != NULL && wt->nf == 701 && wt->ns == 300 && wt->sd == 100 && wt->sb == 20 && wt->fb == 15 && wt->plan != NULL && wt->plan->nrow == 200 && wt->plan->ncol == 130 && wt->plan->w[3][7] == SHARK , "new_wator"); k=7; l=6; print_result ( ricerca_cella (wt->plan, &k, &l, FISH) && k==7 && l==7 , "ricerca_cella (wt->pl, 7, 6, FISH)" ); k=l=0; print_result ( ricerca_cella (wt->plan, &k, &l, SHARK) && k==199 && l==0 , "ricerca_cella (wt->pl, 0, 0, SHARK)" ); k=1; l=3; print_result ( ! ricerca_cella (wt->plan, &k, &l, SHARK) && k==1 && l==3 , "ricerca_cella (wt->pl, 1, 3, SHARK)" ); k=5; l=2; print_result ( ricerca_cella (wt->plan, &k, &l, FISH) && k==5 && ( l==3 || l== 1 ), "ricerca_cella (wt->pl, 5, 2, SHARK)" ); k=20; l=25; print_result ( ricerca_cella (wt->plan, &k, &l, WATER) && ( (k==19 && l==25 ) || ( k== 20 && l== 24 ) ), "ricerca_cella (wt->pl, 20, 25, WATER)" ); print_result ( shark_rule1 ( wt, 0, 2, &k, &l ) == -1 , "shark_rule_1 (0,2)" ); print_result ( shark_rule1 ( wt, 1, 14, &k, &l ) == MOVE, "shark_rule_1 (1,15)" ); print_result ( shark_rule1 ( wt, 7, 6, &k, &l ) == EAT && k==7 && l==7, "shark_rule_1 (7,7)" ); //resetto il pianeta free_wator (wt); wt=new_wator ("custom_test/planet1.dat"); n=10; wt->plan->btime[1][14] = 3; print_result ( ! riproduzione_generica (wt->plan, 1, 14, &k, &l, 4, &n ) && k==1 && l==14 && n==10, "riproduzione_generica (wt->plan, 1, 14) - nothing" ); p=1; g=14; print_result ( riproduzione_generica (wt->plan, 1, 14, &k, &l, 4, &n ) && ricerca_cella (wt->plan, &p, &g, SHARK) && p==k && g==l && n==11, "riproduzione_generica (wt->plan, 1, 14) - born" ); wt->plan->dtime[3][7] = wt->sd; print_result ( shark_rule2 ( wt, 3, 7, &k, &l ) == DEAD && wt->plan->w[3][7] == WATER, "shark_rule2 ( wt, 3, 7) - died" ); print_result ( shark_rule2 ( wt, 7, 6, &k, &l ) == ALIVE && wt->plan->btime[7][6] == 1 , "shark_rule2 ( wt, 7, 6) - nothing" ); wt->plan->btime[7][6] = wt->sb; p=7; g=6; print_result ( shark_rule2 ( wt, 7, 6, &k, &l ) == ALIVE && ricerca_cella ( wt->plan, &p, &g, SHARK ) && p==k && g==l , "shark_rule2 ( wt, 7, 6) - born" ); //resetto il pianeta free_wator (wt); wt=new_wator ("custom_test/planet1.dat"); p=0; g=12; print_result ( fish_rule3 ( wt, 0, 12, &k, &l ) == MOVE && wt->plan->w[0][12] == WATER && ricerca_cella (wt->plan,&p,&g,FISH) && p==k && g==l , "fish_rule_3 ( wt, 0, 12) - moved" ); print_result ( ! fish_rule4 (wt, 5, 70, &k, &l ) && wt->plan->btime[5][70] == 1 , "fish_rule4 (wt, 5, 70) - nothing" ); print_result ( conta_generico ( wt->plan, FISH ) == 701 , "conta_generico ( wt->plan, FISH )" ); print_result ( conta_generico ( wt->plan, SHARK ) == 300 , "conta_generico ( wt->plan, SHARK )" ); print_result ( conta_generico ( wt->plan, WATER ) == wt->plan->ncol*wt->plan->nrow - 701 - 300 , "conta_generico ( wt->plan, WATER )" ); wt->plan->btime[5][70] = wt->fb; p=5; g=70; print_result ( ! fish_rule4 (wt, 5, 70, &k, &l ) && wt->plan->btime[5][70] == 0 && ricerca_cella (wt->plan, &p,&g,FISH) && p==k && g==l , "fish_rule4 (wt, 5, 70) - born" ); //quello in più rispetto a 701 del test di prima è appena nato. Auguri! print_result ( fish_count ( wt->plan ) == wt->nf , "fish_count ( wt->plan ) == wt->nf"); print_result ( shark_count ( wt->plan ) == wt->ns , "fish_count ( wt->plan ) == wt->ns"); //copio il pianeta e lo scrivo sul file. Poi confronto i due file, per vedere se sono uguali copia = (cell_t**) alloca_matrice_generica ( wt->plan->nrow, wt->plan->ncol, sizeof (cell_t), sizeof (cell_t *) ); copia_pianeta (copia, wt->plan->w, wt->plan->nrow, wt->plan->ncol); pl = malloc ( sizeof (planet_t) ); pl->w = copia; pl->nrow = wt->plan->nrow; pl->ncol = wt->plan->ncol; pl->btime = NULL; pl->dtime = NULL; f1 = fopen ( "custom_test/result_wt.dat", "w" ); f2 = fopen ( "custom_test/result_copia.dat", "w" ); print_planet ( f1, wt->plan ); print_planet ( f2, pl ); fclose (f1); fclose (f2); print_result ( confronto_file ( f1,f2 ), "copia_pianeta ()" ); free_wator (wt); free_planet (pl); wt = new_wator ("custom_test/planet1.dat"); free_wator (wt); muntrace(); return 0; }