Files
progettoso/lib/log/taglialegna.c
2022-05-07 21:16:35 +02:00

196 lines
4.7 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.

#define _POSIX_C_SOURCE 200809L
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <pthread.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("taglia_init: calloc");
return NULL;
}
va_list ap;
va_start(ap, n); /* note: by default we have argument promotion,
* but we read only int so thats not a problem */
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("taglia_init: fopen");
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("taglia_init: pthread_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), taglia->file)) < 0) {
perror("taglia_write: 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)) {
perror("taglia_write: time");
goto _error_taglia_log;
}
struct tm tmp_buf;
struct tm *now_tm;
now_tm = gmtime_r(&now, &tmp_buf);
if(!now_tm){
perror("taglia_write: gmtime_r");
goto _error_taglia_log;
}
char buff[15]; /* 13 only should be strictly needed */
if(!strftime(buff, sizeof(buff), "[%T] ", now_tm)) {
perror("taglia_write: strftime");
goto _error_taglia_log;
}
size_t n, m;
pthread_mutex_lock(&taglia->m);
n = fwrite(buff, sizeof(char), strnlen(buff, sizeof(buff)), taglia->file);
if(n < 0){
perror("taglia_write: fwrite");
goto _error_taglia_log_mutex;
}
m = fwrite(buf, sizeof(char), strlen(buf), taglia->file);
if(m < 0){
perror("taglia_write: 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, "Dimensione massima in Mbytes raggiunta dal file storage: %lf 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_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(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_misses);
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);
perror("taglia_stats: snprintf");
return -1;
}