From 92df2e92116f699a7602d138dda69eaa4f8f2fce Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 4 Sep 2021 12:08:00 -0700 Subject: [PATCH] ... --- inc/log.h | 28 ++++++++++++-- src/log.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/setup.c | 2 + 3 files changed, 125 insertions(+), 12 deletions(-) diff --git a/inc/log.h b/inc/log.h index 912681a..63d16b3 100644 --- a/inc/log.h +++ b/inc/log.h @@ -4,9 +4,11 @@ #include #include #include +#include extern int verbose_flag; extern pthread_t logging_thread; +extern pthread_mutex_t logging_mutex; enum log_level { LOG_LEVEL_SILENT = 0, /* suppresses all output */ @@ -15,17 +17,35 @@ enum log_level { LOG_LEVEL_VERBOSE = 3 /* logging and debugging info */ }; -#define log_err(...) log_enqueue(LOG_LEVEL_ERRORS,stderr,__VA_ARGS__) -#define log_info(...) log_enqueue(LOG_LEVEL_VERBOSE,stdout,__VA_ARGS__) -#define log_msg(...) log_enqueue(LOG_LEVEL_DEFAULT,stdout,__VA_ARGS__) +#define log_err(...) log_message(LOG_LEVEL_ERRORS,stderr,__VA_ARGS__) +#define log_info(...) log_message(LOG_LEVEL_VERBOSE,stdout,__VA_ARGS__) +#define log_msg(...) log_message(LOG_LEVEL_DEFAULT,stdout,__VA_ARGS__) + +#define LOG_FLUSH_MESSAGE "flushing log queue...\n" + +#define LOG_ENTRY_MAX_LENGTH 100 +#define LOG_QUEUE_SIZE 100 struct log_entry { enum log_level level; char buf[LOG_ENTRY_MAX_LENGTH]; FILE *out_stream; + struct log_entry *next; +}; + +struct log_helper { + void *p; + struct log_entry *start; + struct log_entry *end; + size_t next; }; -void log_enqueue(enum log_level,FILE*,const char*,...); +struct log_entry *log_dequeue(); +void log_enqueue(struct log_entry*); +int log_entries_init(); +void log_entries_clean(); +void log_flush(); +void log_print(struct log_entry*); void log_message(enum log_level,FILE*,const char*,...); void log_poll(); diff --git a/src/log.c b/src/log.c index 74b2bdb..9b3ee6e 100644 --- a/src/log.c +++ b/src/log.c @@ -2,22 +2,113 @@ int verbose_flag = LOG_LEVEL_DEFAULT; -void log_enqueue(enum log_level level, FILE *out_stream, const char *format,...) { - va_list args; - va_start(args,format); -// vsnprintf(buf,format,args); - va_end(args); +struct log_helper helper; + +struct log_entry *log_dequeue() { + struct log_entry *p; + + pthread_mutex_lock(&logging_mutex); + + if(NULL==helper.start) { + p = NULL; + } else { + p = helper.start; + helper.start = p->next; + } + + pthread_mutex_unlock(&logging_mutex); + + return p; +} + +void log_enqueue(struct log_entry *p) { + pthread_mutex_lock(&logging_mutex); + + if(NULL==helper.start) { + helper.start = p; + helper.end = p; + } else { + helper.end->next = p; + helper.end = p; + } + + pthread_mutex_unlock(&logging_mutex); +} + +int log_entries_init() { + helper.start = NULL; + helper.end = NULL; + helper.next = 0; + + helper.p = malloc(sizeof(struct log_entry(*))*LOG_QUEUE_SIZE+(sizeof(struct log_entry)*LOG_QUEUE_SIZE)); + if(NULL==helper.p) { + perror("malloc"); + return -1; + } + + return 1; +} + +void log_entries_clean() { + free(helper.p); +} + +void log_flush() { + log_err(LOG_FLUSH_MESSAGE); + + pthread_mutex_lock(&logging_mutex); + + while(helper.start!=NULL) { + log_print(helper.start); + helper.start = helper.start->next; + } + + helper.start = NULL; + helper.end = NULL; + helper.next = 0; + + pthread_mutex_unlock(&logging_mutex); +} + +void log_print(struct log_entry *p) { + fputs(p->out_stream,p->buf); } void log_message(enum log_level level, FILE *out_stream, const char *format,...) { if(level>verbose_flag) { return; } va_list args; - + va_start(args,format); if(0==pthread_equal(pthread_self(),logging_thread)) { - log_enqueue(level,out_stream,format,...); + // not on logging_thread + + struct log_entry *p; + size_t offset; + + offset = LOG_QUEUE_SIZE; + while(offset>=LOG_QUEUE_SIZE) { + pthread_mutex_lock(&logging_mutex); + + offset = helper.next; + helper.next++; + + pthread_mutex_unlock(&logging_mutex); + + // out of queue entries + if(offset>=LOG_QUEUE_SIZE) { + log_flush(); + } + } + + p = &(helper.p[offset*sizeof(struct log_entry)]); + + p->level = level; + p->out_stream = out_stream; + p->next = NULL; + vsnprintf(p->buf,LOG_ENTRY_MAX_LENGTH,format,args); + + log_enqueue(p); } else { - va_start(args,format); vfprintf(out_stream,format,args); } diff --git a/src/setup.c b/src/setup.c index 41ae3fb..7e6d37c 100644 --- a/src/setup.c +++ b/src/setup.c @@ -1,8 +1,10 @@ #include pthread_t logging_thread; +pthread_mutex_t logging_mutex = PTHREAD_MUTEX_INITIALIZER; int setup() { + if(log_entries_init()<0) { return -1; } if(pthread_create(&logging_thread,NULL,&log_poll)!=0) { perror("pthread_create"); return -1; -- 2.30.2