#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include #include #include taglia_t *taglia_init(char *file, int n, ...) { int max_files; int max_size; int cache_misses; taglia_t *new = calloc(1, sizeof(taglia_t)); if(new == NULL) { perror("calloc"); return NULL; } va_list ap; va_start(ap, n); // nota: si ha sempre default argument promotion, // ma noi leggiamo solo int quindi ignoriamo il problema max_files = (n<1)?0:va_arg(ap, int); max_size = (n<2)?0:va_arg(ap, int); cache_misses = (n<3)?0:va_arg(ap, int); va_end(ap); if ( (new->file = fopen(file, "w")) == NULL ) { perror("fopen logfile"); goto _error_init; } new->max_files = max_files; new->max_size = max_size; new->cache_misses = cache_misses; if (pthread_mutex_init(&new->m, NULL) != 0) { perror("mutex init"); fclose(new->file); goto _error_init; } return new; _error_init: free(new); return NULL; } void taglia_del(taglia_t *taglia) { fclose(taglia->file); pthread_mutex_destroy(&taglia->m); free(taglia); } size_t taglia_write(taglia_t *taglia, char *buf) { if(!taglia || !buf) { errno = EINVAL; return -1; } size_t n = 0; pthread_mutex_lock(&taglia->m); if ((n = fwrite(buf, sizeof(char), strlen(buf)+1, taglia->file)) < 0) { // strlen conta il numero di caratteri senza EOF quindi aggiungiamo 1 perror("fwrite"); goto _error_write; } pthread_mutex_unlock(&taglia->m); return n; _error_write: pthread_mutex_unlock(&taglia->m); return -1; } size_t taglia_log(taglia_t *taglia, char *buf) { if(!taglia || !buf) { errno = EINVAL; return -1; } time_t now = time(NULL); if(now == (time_t)(-1)) { // errore a ottenere l'ora perror("ERROR: time"); goto _error_taglia_log; } struct tm tmp_buf; struct tm *now_tm; now_tm = gmtime_r(&now, &tmp_buf); if(!now_tm){ perror("ERROR: gmtime_r"); goto _error_taglia_log; } char buff[15]; // 13 only should strictly needed if(!strftime(buff, sizeof(buff), "[%T] ", now_tm)) { perror("ERROR: strftime"); goto _error_taglia_log; } size_t n, m; pthread_mutex_lock(&taglia->m); if((n = fwrite(buff, sizeof(char), strnlen(buff, sizeof(buff)), taglia->file)) < 0){ perror("ERROR: fwrite"); goto _error_taglia_log_mutex; } if((m = fwrite(buf, sizeof(char), strlen(buf)+1, taglia->file)) < 0){ // strlen conta il numero di caratteri senza EOF quindi aggiungiamo 1 perror("ERROR: fwrite"); goto _error_taglia_log_mutex; } pthread_mutex_unlock(&taglia->m); fflush(taglia->file); return n+m; _error_taglia_log_mutex: pthread_mutex_unlock(&taglia->m); _error_taglia_log: return -1; } int taglia_update(taglia_t *taglia, queueT *q, int miss) { if(!taglia || !q) { errno = EINVAL; return -1; } pthread_mutex_lock(&taglia->m); size_t len = getLen(q); size_t size = getSize(q); taglia->max_files = (len > taglia->max_files)?len:taglia->max_files; taglia->max_size = (size > taglia->max_size)?size:taglia->max_size; taglia->cache_misses += (miss>0)?miss:0; pthread_mutex_unlock(&taglia->m); return 0; } int taglia_stats(taglia_t *taglia, FILE *stream) { if (!taglia) { errno = EINVAL; return -1; } pthread_mutex_lock(&taglia->m); double res = ((double) taglia->max_size)/((double) 1000000); fprintf(stream, "Numero di file massimo memorizzato nel server: %zu\n", taglia->max_files); fprintf(stream, "Dimensione massima in Mbytes raggiunta dal file storage: %.2lf MB\n", res); fprintf(stream, "Numero di volte in cui l’algoritmo di rimpiazzamento della cache è stato eseguito per selezionare uno o più file \"vittima\": %zu\n", taglia->cache_misses); fflush(stream); char tmp_buf[2048]; int n = 0; size_t m = sizeof(tmp_buf); n += snprintf(tmp_buf+n, m-n, "Numero di file massimo memorizzato nel server: %zu\n", taglia->max_files); if(mcache_misses); if(mm); if(taglia_write(taglia, tmp_buf) < 0) return -1; return 0; _error_taglia_stats: pthread_mutex_unlock(&taglia->m); return -1; }