parent
916cf34a0e
commit
75ecdb3f95
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct mem_logging_obj {
|
||||||
|
uint32_t log_size;
|
||||||
|
char *logger;
|
||||||
|
uint32_t offset;
|
||||||
|
FILE* fout;
|
||||||
|
};
|
||||||
|
|
||||||
|
void mem_log_init(uint32_t log_size, char const* file);
|
||||||
|
void mem_log_init2(uint32_t log_size, FILE* file);
|
||||||
|
void mem_log(char const * fmt, ...);
|
||||||
|
void dump_log_to_file();
|
@ -0,0 +1,125 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include "memlogging.h"
|
||||||
|
#include "panic.h"
|
||||||
|
|
||||||
|
__thread struct mem_logging_obj log_obj;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize memory log. This should be called in each worker thread.
|
||||||
|
* Every worker thread writes log to its own memory.
|
||||||
|
* @param log_size the number of bytes of memory to allocate for logging
|
||||||
|
* @param file the FILE pointer to an opened file, each worker thread will
|
||||||
|
* dump the memory log to this file when sledge exits. The file is
|
||||||
|
* defined by an environment variable
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mem_log_init2(uint32_t log_size, FILE* file)
|
||||||
|
{
|
||||||
|
#ifndef LOG_RUNTIME_MEM_LOG
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
log_obj.log_size = log_size;
|
||||||
|
log_obj.logger = (char *)malloc(log_size);
|
||||||
|
if (!log_obj.logger) {
|
||||||
|
panic("failed to allocate memory for logging\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
log_obj.offset = 0;
|
||||||
|
log_obj.fout = file;
|
||||||
|
if (!log_obj.fout) {
|
||||||
|
panic("failed to open log file:%s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize memory log. This should be called in each worker thread.
|
||||||
|
* Every worker thread writes log to its own memory.
|
||||||
|
* @param log_size the number of bytes of memory to allocate for logging
|
||||||
|
* @param file the file to dump the memory log when sledge exits
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mem_log_init(uint32_t log_size, char const* file)
|
||||||
|
{
|
||||||
|
#ifndef LOG_RUNTIME_MEM_LOG
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
log_obj.log_size = log_size;
|
||||||
|
log_obj.logger = (char *)malloc(log_size);
|
||||||
|
if (!log_obj.logger) {
|
||||||
|
panic("failed to allocate memory for logging\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
log_obj.offset = 0;
|
||||||
|
log_obj.fout = fopen(file, "a+");
|
||||||
|
if (!log_obj.fout) {
|
||||||
|
panic("failed to open log file:%s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints log to memory
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mem_log(char const * fmt, ...)
|
||||||
|
{
|
||||||
|
#ifndef LOG_RUNTIME_MEM_LOG
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
assert(log_obj.logger);
|
||||||
|
assert(log_obj.fout);
|
||||||
|
|
||||||
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
int n = vsnprintf(log_obj.logger + log_obj.offset, log_obj.log_size - log_obj.offset, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
if (n < 0) {
|
||||||
|
/* Based on the doc of vsnprintf, the write is failed if n is negative */
|
||||||
|
panic("failed to write data to memory, return value:%d\n", n);
|
||||||
|
} else if (n >= log_obj.log_size - log_obj.offset) {
|
||||||
|
/* Memory is full, realloc memory */
|
||||||
|
char* old_logger = log_obj.logger;
|
||||||
|
|
||||||
|
while (n >=log_obj.log_size - log_obj.offset) {
|
||||||
|
log_obj.logger = (char *)realloc(log_obj.logger, log_obj.log_size * 2);
|
||||||
|
if (!log_obj.logger) {
|
||||||
|
log_obj.logger = old_logger;
|
||||||
|
dump_log_to_file(log_obj);
|
||||||
|
panic("failed to realloc memory for logging\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
log_obj.log_size = log_obj.log_size * 2;
|
||||||
|
va_start(va, fmt);
|
||||||
|
n = vsnprintf(log_obj.logger + log_obj.offset, log_obj.log_size - log_obj.offset, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
log_obj.offset += n;
|
||||||
|
} else {
|
||||||
|
/* Write Success */
|
||||||
|
log_obj.offset += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump log from memory to file. This should be called when a worker thread receives SIGINT signal
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dump_log_to_file()
|
||||||
|
{
|
||||||
|
#ifndef LOG_RUNTIME_MEM_LOG
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
assert(log_obj.logger);
|
||||||
|
assert(log_obj.fout);
|
||||||
|
|
||||||
|
uint32_t write_bytes = 0;
|
||||||
|
while(write_bytes != log_obj.offset) {
|
||||||
|
int return_bytes = fprintf(log_obj.fout, "%s", log_obj.logger + write_bytes);
|
||||||
|
write_bytes += return_bytes;
|
||||||
|
}
|
||||||
|
fflush(log_obj.fout);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in new issue