style for files taglialegna.* apiFile.*
This commit is contained in:
@ -7,8 +7,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <taglialegna.h>
|
#include "taglialegna.h"
|
||||||
#include <fileQueue.h>
|
#include "fileQueue.h"
|
||||||
|
|
||||||
taglia_t *taglia_init(char *file, int n, ...) {
|
taglia_t *taglia_init(char *file, int n, ...) {
|
||||||
int max_files;
|
int max_files;
|
||||||
@ -17,19 +17,19 @@ taglia_t *taglia_init(char *file, int n, ...) {
|
|||||||
|
|
||||||
taglia_t *new = calloc(1, sizeof(taglia_t));
|
taglia_t *new = calloc(1, sizeof(taglia_t));
|
||||||
if(new == NULL) {
|
if(new == NULL) {
|
||||||
perror("calloc");
|
perror("taglia_init: calloc");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, n); // nota: si ha sempre default argument promotion,
|
va_start(ap, n); /* note: by default we have argument promotion,
|
||||||
// ma noi leggiamo solo int quindi ignoriamo il problema
|
* but we read only int so thats not a problem */
|
||||||
max_files = (n<1)?0:va_arg(ap, int);
|
max_files = (n<1)?0:va_arg(ap, int);
|
||||||
max_size = (n<2)?0:va_arg(ap, int);
|
max_size = (n<2)?0:va_arg(ap, int);
|
||||||
cache_misses = (n<3)?0:va_arg(ap, int);
|
cache_misses = (n<3)?0:va_arg(ap, int);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if ( (new->file = fopen(file, "w")) == NULL ) {
|
if ( (new->file = fopen(file, "w")) == NULL ) {
|
||||||
perror("fopen logfile");
|
perror("taglia_init: fopen");
|
||||||
goto _error_init;
|
goto _error_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ taglia_t *taglia_init(char *file, int n, ...) {
|
|||||||
new->cache_misses = cache_misses;
|
new->cache_misses = cache_misses;
|
||||||
|
|
||||||
if (pthread_mutex_init(&new->m, NULL) != 0) {
|
if (pthread_mutex_init(&new->m, NULL) != 0) {
|
||||||
perror("mutex init");
|
perror("taglia_init: pthread_mutex_init");
|
||||||
fclose(new->file);
|
fclose(new->file);
|
||||||
goto _error_init;
|
goto _error_init;
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ size_t taglia_write(taglia_t *taglia, char *buf) {
|
|||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
pthread_mutex_lock(&taglia->m);
|
pthread_mutex_lock(&taglia->m);
|
||||||
if ((n = fwrite(buf, sizeof(char), strlen(buf), taglia->file)) < 0) {
|
if ((n = fwrite(buf, sizeof(char), strlen(buf), taglia->file)) < 0) {
|
||||||
perror("fwrite");
|
perror("taglia_write: fwrite");
|
||||||
goto _error_write;
|
goto _error_write;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&taglia->m);
|
pthread_mutex_unlock(&taglia->m);
|
||||||
@ -83,8 +83,8 @@ size_t taglia_log(taglia_t *taglia, char *buf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
if(now == (time_t)(-1)) { // errore a ottenere l'ora
|
if(now == (time_t)(-1)) {
|
||||||
perror("ERROR: time");
|
perror("taglia_write: time");
|
||||||
goto _error_taglia_log;
|
goto _error_taglia_log;
|
||||||
}
|
}
|
||||||
struct tm tmp_buf;
|
struct tm tmp_buf;
|
||||||
@ -92,26 +92,28 @@ size_t taglia_log(taglia_t *taglia, char *buf) {
|
|||||||
|
|
||||||
now_tm = gmtime_r(&now, &tmp_buf);
|
now_tm = gmtime_r(&now, &tmp_buf);
|
||||||
if(!now_tm){
|
if(!now_tm){
|
||||||
perror("ERROR: gmtime_r");
|
perror("taglia_write: gmtime_r");
|
||||||
goto _error_taglia_log;
|
goto _error_taglia_log;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buff[15]; // 13 only should strictly needed
|
char buff[15]; /* 13 only should be strictly needed */
|
||||||
|
|
||||||
if(!strftime(buff, sizeof(buff), "[%T] ", now_tm)) {
|
if(!strftime(buff, sizeof(buff), "[%T] ", now_tm)) {
|
||||||
perror("ERROR: strftime");
|
perror("taglia_write: strftime");
|
||||||
goto _error_taglia_log;
|
goto _error_taglia_log;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t n, m;
|
size_t n, m;
|
||||||
pthread_mutex_lock(&taglia->m);
|
pthread_mutex_lock(&taglia->m);
|
||||||
if((n = fwrite(buff, sizeof(char), strnlen(buff, sizeof(buff)), taglia->file)) < 0){
|
n = fwrite(buff, sizeof(char), strnlen(buff, sizeof(buff)), taglia->file);
|
||||||
perror("ERROR: fwrite");
|
if(n < 0){
|
||||||
|
perror("taglia_write: fwrite");
|
||||||
goto _error_taglia_log_mutex;
|
goto _error_taglia_log_mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((m = fwrite(buf, sizeof(char), strlen(buf), taglia->file)) < 0){
|
m = fwrite(buf, sizeof(char), strlen(buf), taglia->file);
|
||||||
perror("ERROR: fwrite");
|
if(m < 0){
|
||||||
|
perror("taglia_write: fwrite");
|
||||||
goto _error_taglia_log_mutex;
|
goto _error_taglia_log_mutex;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&taglia->m);
|
pthread_mutex_unlock(&taglia->m);
|
||||||
@ -156,21 +158,27 @@ int taglia_stats(taglia_t *taglia, FILE *stream) {
|
|||||||
|
|
||||||
double res = ((double) taglia->max_size)/((double) 1000000);
|
double res = ((double) taglia->max_size)/((double) 1000000);
|
||||||
|
|
||||||
fprintf(stream, "Numero di file massimo memorizzato nel server: %zu\n", taglia->max_files);
|
fprintf(stream, "Numero di file massimo memorizzato nel server: %zu\n",
|
||||||
// fprintf(stream, "Dimensione massima in Mbytes raggiunta dal file storage: %.2lf MB\n", res);
|
taglia->max_files);
|
||||||
fprintf(stream, "Dimensione massima in Mbytes raggiunta dal file storage: %lf MB\n", res);
|
/* 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);
|
fprintf(stream, "Dimensione massima in Mbytes raggiunta dal file storage: %lf 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);
|
fflush(stream);
|
||||||
|
|
||||||
|
|
||||||
char tmp_buf[2048];
|
char tmp_buf[2048];
|
||||||
int n = 0;
|
int n = 0;
|
||||||
size_t m = sizeof(tmp_buf);
|
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);
|
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;
|
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);
|
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;
|
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_misses);
|
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_misses);
|
||||||
if(m<n) goto _error_taglia_stats;
|
if(m<n) goto _error_taglia_stats;
|
||||||
|
|
||||||
pthread_mutex_unlock(&taglia->m);
|
pthread_mutex_unlock(&taglia->m);
|
||||||
@ -182,5 +190,6 @@ int taglia_stats(taglia_t *taglia, FILE *stream) {
|
|||||||
|
|
||||||
_error_taglia_stats:
|
_error_taglia_stats:
|
||||||
pthread_mutex_unlock(&taglia->m);
|
pthread_mutex_unlock(&taglia->m);
|
||||||
|
perror("taglia_stats: snprintf");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,39 +5,74 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <fileQueue.h>
|
#include "fileQueue.h"
|
||||||
|
|
||||||
typedef struct taglia_s {
|
typedef struct taglia_s {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
size_t max_files;
|
size_t max_files;
|
||||||
long max_size;
|
long max_size;
|
||||||
size_t cache_misses;
|
size_t cache_misses;
|
||||||
pthread_mutex_t m; // per sincronizzare le scritture al file
|
pthread_mutex_t m; /* per sincronizzare le scritture al file */
|
||||||
} taglia_t;
|
} taglia_t;
|
||||||
|
|
||||||
// crea una nuova istanza
|
|
||||||
// \param file: file su cui scrivere i dati
|
/**
|
||||||
// \param n: numero di parametri opzionali
|
* @brief Creates new instance
|
||||||
// parametri opzionali in questo ordine:
|
*
|
||||||
// max_files, max_size, cache_misses
|
* @param file path to file to write into
|
||||||
// \return istanza creata, NULL se errore
|
* @param n number of optional parameters, in order:
|
||||||
|
* int max_files, int max_size, int cache_misses
|
||||||
|
* @return created istance, NULL if error
|
||||||
|
*/
|
||||||
taglia_t *taglia_init(char *file, int n, ...);
|
taglia_t *taglia_init(char *file, int n, ...);
|
||||||
|
|
||||||
// elimina un'istanza deallocando e chiudendo le rispettive risorse
|
|
||||||
|
/**
|
||||||
|
* @brief Deallocates instance
|
||||||
|
*
|
||||||
|
* @param taglia instance to deallocate
|
||||||
|
*/
|
||||||
void taglia_del(taglia_t *taglia);
|
void taglia_del(taglia_t *taglia);
|
||||||
|
|
||||||
// scrive quello contenuto dentro a buf sul file
|
|
||||||
// \return numero di char scritti, -1 se errore
|
/**
|
||||||
|
* @brief Writes buffer to the log
|
||||||
|
*
|
||||||
|
* @param taglia
|
||||||
|
* @param buf NULL terminated string to write
|
||||||
|
* @return number of char written, -1 if error occurred
|
||||||
|
*/
|
||||||
size_t taglia_write(taglia_t *taglia, char *buf);
|
size_t taglia_write(taglia_t *taglia, char *buf);
|
||||||
|
|
||||||
// scrive il contenuto di buf sul file con ora associata
|
|
||||||
|
/**
|
||||||
|
* @brief Writes buffer to the log with timestamp
|
||||||
|
*
|
||||||
|
* @param taglia
|
||||||
|
* @param buf NULL terminated string to write
|
||||||
|
* @return number of char written, -1 if error occurred
|
||||||
|
*/
|
||||||
size_t taglia_log(taglia_t *taglia, char *buf);
|
size_t taglia_log(taglia_t *taglia, char *buf);
|
||||||
|
|
||||||
// update delle statistiche
|
|
||||||
// \return 0 successo, -1 errore
|
/**
|
||||||
|
* @brief Updates statistics
|
||||||
|
*
|
||||||
|
* @param taglia
|
||||||
|
* @param queue structure that holds the files
|
||||||
|
* @param miss number of cache misses to add
|
||||||
|
* @return 1 if success, -1 if error occurred
|
||||||
|
*/
|
||||||
int taglia_update(taglia_t *taglia, queueT *queue, int miss);
|
int taglia_update(taglia_t *taglia, queueT *queue, int miss);
|
||||||
|
|
||||||
// print delle statistiche attuali su stream
|
|
||||||
|
/**
|
||||||
|
* @brief Writes stats to the stream and to the log
|
||||||
|
*
|
||||||
|
* @param taglia
|
||||||
|
* @param stream
|
||||||
|
* @return 0 if success, -1 if error occurred
|
||||||
|
*/
|
||||||
int taglia_stats(taglia_t *taglia, FILE *stream);
|
int taglia_stats(taglia_t *taglia, FILE *stream);
|
||||||
|
|
||||||
#endif /* _TAGLIALEGNA */
|
#endif /* _TAGLIALEGNA */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -4,64 +4,159 @@
|
|||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <fileQueue.h>
|
#include "fileQueue.h"
|
||||||
#include <taglialegna.h>
|
#include "taglialegna.h"
|
||||||
/* TODO: finire tutte le descrizioni */
|
|
||||||
|
|
||||||
#define C_CREATE 1
|
#define C_CREATE 1
|
||||||
#define C_LOCK 2
|
#define C_LOCK 2
|
||||||
|
|
||||||
|
/* structure for the list of clients waiting for a lock */
|
||||||
// Lista dei client in attesa su una lock
|
|
||||||
typedef struct struct_waiting {
|
typedef struct struct_waiting {
|
||||||
long fd; // client in attesa
|
long fd; /* client waiting */
|
||||||
char *file; // file su cui si vuole acquisire la lock
|
char *file; /* file waiting the lock on */
|
||||||
struct struct_waiting *next; // puntatore al prossimo elemento della lista
|
struct struct_waiting *next;
|
||||||
} waiting_t;
|
} waiting_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apri o crea un nuovo file
|
* @brief Open or create new file
|
||||||
* \param filepath: nome del file
|
*
|
||||||
* \param flags:
|
* @param filepath name of the file
|
||||||
* \param q: queue in cui inserire il file
|
* @param flags
|
||||||
* \param fd_c: owner
|
* @param q queue to insert the file into
|
||||||
* \param taglia_t:
|
* @param fd_c owner
|
||||||
|
* @param taglia
|
||||||
*/
|
*/
|
||||||
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia);
|
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia);
|
||||||
|
|
||||||
// Leggi un file e invialo al client
|
|
||||||
|
/**
|
||||||
|
* @brief Read a file and send it to a client
|
||||||
|
*
|
||||||
|
* @param filepath name of the file
|
||||||
|
* @param q queue where the file is
|
||||||
|
* @param fd_c client
|
||||||
|
* @param taglia
|
||||||
|
*/
|
||||||
void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia);
|
void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia);
|
||||||
|
|
||||||
// Invia al client $n file qualsiasi dalla queue
|
|
||||||
|
/**
|
||||||
|
* @brief Send to the client n files from the queue
|
||||||
|
*
|
||||||
|
* @param num number of files to send
|
||||||
|
* @param q
|
||||||
|
* @param fd_c client
|
||||||
|
* @param taglia
|
||||||
|
*/
|
||||||
void readNFiles(int num, queueT *q, long fd_c, taglia_t *taglia);
|
void readNFiles(int num, queueT *q, long fd_c, taglia_t *taglia);
|
||||||
|
|
||||||
// Scrivi dati su un file già creato (append o overwrite)
|
|
||||||
|
/**
|
||||||
|
* @brief Write to a file
|
||||||
|
*
|
||||||
|
* @param filepath
|
||||||
|
* @param size
|
||||||
|
* @param q
|
||||||
|
* @param fd_c client
|
||||||
|
* @param taglia
|
||||||
|
* @param append true if append, false if overwrite
|
||||||
|
*/
|
||||||
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *taglia, int append);
|
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *taglia, int append);
|
||||||
|
|
||||||
// Acquisisci lock di un file
|
|
||||||
|
/**
|
||||||
|
* @brief Get the lock of a file
|
||||||
|
*
|
||||||
|
* @param filepath
|
||||||
|
* @param q
|
||||||
|
* @param fd_c client
|
||||||
|
* @param taglia
|
||||||
|
* @param lock lock of the waiting_t list
|
||||||
|
* @param waiting
|
||||||
|
*/
|
||||||
void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting);
|
void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting);
|
||||||
|
|
||||||
// Rilascia una Lock di un file
|
|
||||||
|
/**
|
||||||
|
* @brief Relese a lock
|
||||||
|
*
|
||||||
|
* @param filepath
|
||||||
|
* @param q
|
||||||
|
* @param fd_c client
|
||||||
|
* @param taglia
|
||||||
|
* @param lock lock of the waiting_t list
|
||||||
|
* @param waiting
|
||||||
|
*/
|
||||||
void unlockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting);
|
void unlockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting);
|
||||||
|
|
||||||
// Chiudi un file
|
|
||||||
|
/**
|
||||||
|
* @brief Close a file and relese locks
|
||||||
|
*
|
||||||
|
* @param filepath
|
||||||
|
* @param q
|
||||||
|
* @param fd_c client
|
||||||
|
* @param taglia
|
||||||
|
* @param lock lock of the waiting_t list
|
||||||
|
* @param waiting
|
||||||
|
*/
|
||||||
void closeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting);
|
void closeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting);
|
||||||
|
|
||||||
// Rimuovi un file
|
|
||||||
|
/**
|
||||||
|
* @brief Delete a file
|
||||||
|
*
|
||||||
|
* @param filepath
|
||||||
|
* @param q
|
||||||
|
* @param fd_c client
|
||||||
|
* @param taglia
|
||||||
|
* @param lock lock of the waiting_t list
|
||||||
|
* @param waiting
|
||||||
|
*/
|
||||||
void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting);
|
void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waiting_t **waiting);
|
||||||
|
|
||||||
|
|
||||||
// Funzione ausiliaria che invia un file al client
|
/**
|
||||||
|
* @brief Send a file to the client
|
||||||
|
*
|
||||||
|
* @param f file to send
|
||||||
|
* @param fd_c client
|
||||||
|
* @param taglia
|
||||||
|
* @return 0 if success, -1 if error
|
||||||
|
*/
|
||||||
int sendFile(fileT *f, long fd_c, taglia_t *taglia);
|
int sendFile(fileT *f, long fd_c, taglia_t *taglia);
|
||||||
|
|
||||||
// Aggiunge una coppia client/file alla coda in attesa di ottenere una lock
|
/**
|
||||||
|
* @brief Add the client to the waiting list for the lock on the file
|
||||||
|
*
|
||||||
|
* @pre the lock of the waiting list must be acquired
|
||||||
|
*
|
||||||
|
* @param waiting
|
||||||
|
* @param filepath
|
||||||
|
* @param fd_c client
|
||||||
|
* @return 0 if success, -1 if error
|
||||||
|
*/
|
||||||
int addWaiting(waiting_t **waiting, char *filepath, int fd_c);
|
int addWaiting(waiting_t **waiting, char *filepath, int fd_c);
|
||||||
|
|
||||||
// Ottiene il primo client in attesa su una lock di un determinato file
|
|
||||||
|
/**
|
||||||
|
* @brief Delete a file
|
||||||
|
*
|
||||||
|
* @pre the lock of the waiting list must be acquired
|
||||||
|
*
|
||||||
|
* @param waiting
|
||||||
|
* @param filepath
|
||||||
|
* @return the file descriptor of the client or -1 if no found
|
||||||
|
*/
|
||||||
int removeFirstWaiting(waiting_t **waiting, char *filepath);
|
int removeFirstWaiting(waiting_t **waiting, char *filepath);
|
||||||
|
|
||||||
// Distrugge la lista d'attesa e ne libera la memoria
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the waiting_t structure
|
||||||
|
*
|
||||||
|
* @param waiting
|
||||||
|
*/
|
||||||
void clearWaiting(waiting_t **waiting);
|
void clearWaiting(waiting_t **waiting);
|
||||||
|
|
||||||
#endif // _API_FILE
|
#endif // _API_FILE
|
||||||
|
|||||||
Reference in New Issue
Block a user