Librearia di log
This commit is contained in:
181
lib/log/taglialegna.c
Normal file
181
lib/log/taglialegna.c
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <taglialegna.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 l’algoritmo 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 l’algoritmo 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;
|
||||||
|
}
|
||||||
40
lib/log/taglialegna.h
Normal file
40
lib/log/taglialegna.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _TAGLIALEGNA
|
||||||
|
#define _TAGLIALEGNA
|
||||||
|
|
||||||
|
#include <fileQueue.h>
|
||||||
|
|
||||||
|
typedef struct taglia_s {
|
||||||
|
FILE *file;
|
||||||
|
size_t max_files;
|
||||||
|
long max_size;
|
||||||
|
size_t cache_misses;
|
||||||
|
pthread_mutex_t m; // per sincronizzare le scritture al file
|
||||||
|
} taglia_t;
|
||||||
|
|
||||||
|
// crea una nuova istanza
|
||||||
|
// \param file: file su cui scrivere i dati
|
||||||
|
// \param n: numero di parametri opzionali
|
||||||
|
// parametri opzionali in questo ordine:
|
||||||
|
// max_files, max_size, cache_misses
|
||||||
|
// \return istanza creata, NULL se errore
|
||||||
|
taglia_t *taglia_init(char *file, int n, ...);
|
||||||
|
|
||||||
|
// elimina un'istanza deallocando e chiudendo le rispettive risorse
|
||||||
|
void taglia_del(taglia_t *taglia);
|
||||||
|
|
||||||
|
// scrive quello contenuto dentro a buf sul file
|
||||||
|
// \return numero di char scritti, -1 se errore
|
||||||
|
size_t taglia_write(taglia_t *taglia, char *buf);
|
||||||
|
|
||||||
|
// scrive il contenuto di buf sul file con ora associata
|
||||||
|
size_t taglia_log(taglia_t *taglia, char *buf);
|
||||||
|
|
||||||
|
// update delle statistiche
|
||||||
|
// \return 0 successo, -1 errore
|
||||||
|
int taglia_update(taglia_t *taglia, queueT *queue, int miss);
|
||||||
|
|
||||||
|
// print delle statistiche attuali su stream
|
||||||
|
int taglia_stats(taglia_t *taglia, FILE *stream);
|
||||||
|
|
||||||
|
#endif /* _TAGLIALEGNA */
|
||||||
13
src/server.c
13
src/server.c
@ -54,7 +54,7 @@ static void checkargs(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
// TODO read config file
|
// read config file
|
||||||
checkargs(argc, argv);
|
checkargs(argc, argv);
|
||||||
ini_t *config = ini_load(argv[1]);
|
ini_t *config = ini_load(argv[1]);
|
||||||
int threadsInPool; CONFGETINT(threadsInPool, config, "threadpool", "quantity", NULL, 10);
|
int threadsInPool; CONFGETINT(threadsInPool, config, "threadpool", "quantity", NULL, 10);
|
||||||
@ -64,12 +64,10 @@ int main(int argc, char *argv[]) {
|
|||||||
ini_free(config);
|
ini_free(config);
|
||||||
|
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
sigemptyset(&mask);
|
sigfillset(&mask);
|
||||||
sigaddset(&mask, SIGINT);
|
sigdelset(&mask, SIGPIPE); // tolgo soltanto la sigpipe
|
||||||
sigaddset(&mask, SIGQUIT);
|
|
||||||
sigaddset(&mask, SIGTERM);
|
|
||||||
|
|
||||||
if (pthread_sigmask(SIG_BLOCK, &mask, NULL) != 0) {
|
if (pthread_sigmask(SIG_SETMASK, &mask, NULL) != 0) {
|
||||||
fprintf(stderr, "ERROR setting mask\n");
|
fprintf(stderr, "ERROR setting mask\n");
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
}
|
}
|
||||||
@ -83,6 +81,9 @@ int main(int argc, char *argv[]) {
|
|||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove("mysock"); maybe necessary???
|
||||||
|
|
||||||
|
|
||||||
printf("File Server ready.");
|
printf("File Server ready.");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user