Files
progettoso/lib/log/taglialegna.c
2022-03-22 19:35:06 +01:00

183 lines
4.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <taglialegna.h>
#include <fileQueue.h>
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), sizeof(buff), taglia->file)) < 0){
perror("ERROR: fwrite");
goto _error_taglia_log_mutex;
}
if((m = fwrite(buf, sizeof(char), strlen(buff)+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);
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;
logFileT->cache_miss += (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 lalgoritmo di rimpiazzamento della cache è stato eseguito per selezionare uno o più file \"vittima\": %zu\n", taglia->cache_miss);
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(m<n) goto _error_taglia_stats;
n += snprintf(tmp_buf+n, m-n, "Dimensione massima in Mbytes raggiunta dal file storage: %.2lf MB\n", res);
if(m<n) goto _error_taglia_stats;
n += snprintf(tmp_buf+n, m-n, "Numero di volte in cui lalgoritmo di rimpiazzamento della cache è stato eseguito per selezionare uno o più file \"vittima\": %zu\n", taglia->cache_miss);
if(m<n) goto _error_taglia_stats;
pthread_mutex_unlock(&taglia->m);
if(taglia_write(taglia, tmp_buf) < 0)
return -1;
return 0;
_error_taglia_stats:
pthread_mutex_unlock(&taglia->m);
return -1;
}