Reindented server/core/memlog.c
This commit is contained in:
@ -22,8 +22,8 @@
|
|||||||
* @verbatim
|
* @verbatim
|
||||||
* Revision History
|
* Revision History
|
||||||
*
|
*
|
||||||
* Date Who Description
|
* Date Who Description
|
||||||
* 26/09/14 Mark Riddoch Initial implementation
|
* 26/09/14 Mark Riddoch Initial implementation
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -33,128 +33,140 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
static MEMLOG *memlogs = NULL;
|
static MEMLOG *memlogs = NULL;
|
||||||
static SPINLOCK memlock = SPINLOCK_INIT;
|
static SPINLOCK memlock = SPINLOCK_INIT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of a memory logger.
|
* Create a new instance of a memory logger.
|
||||||
*
|
*
|
||||||
* @param name The name of the memory log
|
* @param name The name of the memory log
|
||||||
* @param type The type of item being logged
|
* @param type The type of item being logged
|
||||||
* @param size The number of items to store in memory before flushign to disk
|
* @param size The number of items to store in memory before flushign to disk
|
||||||
*
|
*
|
||||||
* @return MEMLOG* A memory log handle
|
* @return MEMLOG* A memory log handle
|
||||||
*/
|
*/
|
||||||
MEMLOG *
|
MEMLOG *
|
||||||
memlog_create(char *name, MEMLOGTYPE type, int size)
|
memlog_create(char *name, MEMLOGTYPE type, int size)
|
||||||
{
|
{
|
||||||
MEMLOG *log;
|
MEMLOG *log;
|
||||||
|
|
||||||
if ((log = (MEMLOG *)malloc(sizeof(MEMLOG))) == NULL)
|
if ((log = (MEMLOG *)malloc(sizeof(MEMLOG))) == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
log->name = strdup(name);
|
log->name = strdup(name);
|
||||||
spinlock_init(&log->lock);
|
spinlock_init(&log->lock);
|
||||||
log->type = type;
|
log->type = type;
|
||||||
log->offset = 0;
|
log->offset = 0;
|
||||||
log->size = size;
|
log->size = size;
|
||||||
log->flags = 0;
|
log->flags = 0;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ML_INT:
|
case ML_INT:
|
||||||
log->values = malloc(sizeof(int) * size);
|
log->values = malloc(sizeof(int) * size);
|
||||||
break;
|
break;
|
||||||
case ML_LONG:
|
case ML_LONG:
|
||||||
log->values = malloc(sizeof(long) * size);
|
log->values = malloc(sizeof(long) * size);
|
||||||
break;
|
break;
|
||||||
case ML_LONGLONG:
|
case ML_LONGLONG:
|
||||||
log->values = malloc(sizeof(long long) * size);
|
log->values = malloc(sizeof(long long) * size);
|
||||||
break;
|
break;
|
||||||
case ML_STRING:
|
case ML_STRING:
|
||||||
log->values = malloc(sizeof(char *) * size);
|
log->values = malloc(sizeof(char *) * size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (log->values == NULL)
|
if (log->values == NULL)
|
||||||
{
|
{
|
||||||
free(log);
|
free(log);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
spinlock_acquire(&memlock);
|
spinlock_acquire(&memlock);
|
||||||
log->next = memlogs;
|
log->next = memlogs;
|
||||||
memlogs = log;
|
memlogs = log;
|
||||||
spinlock_release(&memlock);
|
spinlock_release(&memlock);
|
||||||
|
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a memory logger any unwritten data will be flushed to disk
|
* Destroy a memory logger any unwritten data will be flushed to disk
|
||||||
*
|
*
|
||||||
* @param log The memory log to destroy
|
* @param log The memory log to destroy
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
memlog_destroy(MEMLOG *log)
|
memlog_destroy(MEMLOG *log)
|
||||||
{
|
{
|
||||||
MEMLOG *ptr;
|
MEMLOG *ptr;
|
||||||
|
|
||||||
if ((log->flags & MLNOAUTOFLUSH) == 0)
|
if ((log->flags & MLNOAUTOFLUSH) == 0)
|
||||||
memlog_flush(log);
|
{
|
||||||
free(log->values);
|
memlog_flush(log);
|
||||||
|
}
|
||||||
|
free(log->values);
|
||||||
|
|
||||||
spinlock_acquire(&memlock);
|
spinlock_acquire(&memlock);
|
||||||
if (memlogs == log)
|
if (memlogs == log)
|
||||||
memlogs = log->next;
|
{
|
||||||
else
|
memlogs = log->next;
|
||||||
{
|
}
|
||||||
ptr = memlogs;
|
else
|
||||||
while (ptr && ptr->next != log)
|
{
|
||||||
ptr = ptr->next;
|
ptr = memlogs;
|
||||||
if (ptr)
|
while (ptr && ptr->next != log)
|
||||||
ptr->next = log->next;
|
{
|
||||||
}
|
ptr = ptr->next;
|
||||||
spinlock_release(&memlock);
|
}
|
||||||
free(log->name);
|
if (ptr)
|
||||||
free(log);
|
{
|
||||||
|
ptr->next = log->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spinlock_release(&memlock);
|
||||||
|
free(log->name);
|
||||||
|
free(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a data item to the memory logger
|
* Log a data item to the memory logger
|
||||||
*
|
*
|
||||||
* @param log The memory logger
|
* @param log The memory logger
|
||||||
* @param value The value to log
|
* @param value The value to log
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
memlog_log(MEMLOG *log, void *value)
|
memlog_log(MEMLOG *log, void *value)
|
||||||
{
|
{
|
||||||
if (!log)
|
if (!log)
|
||||||
return;
|
{
|
||||||
spinlock_acquire(&log->lock);
|
return;
|
||||||
switch (log->type)
|
}
|
||||||
{
|
spinlock_acquire(&log->lock);
|
||||||
case ML_INT:
|
switch (log->type)
|
||||||
((int *)(log->values))[log->offset] = (intptr_t)value;
|
{
|
||||||
break;
|
case ML_INT:
|
||||||
case ML_LONG:
|
((int *)(log->values))[log->offset] = (intptr_t)value;
|
||||||
((long *)(log->values))[log->offset] = (long)value;
|
break;
|
||||||
break;
|
case ML_LONG:
|
||||||
case ML_LONGLONG:
|
((long *)(log->values))[log->offset] = (long)value;
|
||||||
((long long *)(log->values))[log->offset] = (long long)value;
|
break;
|
||||||
break;
|
case ML_LONGLONG:
|
||||||
case ML_STRING:
|
((long long *)(log->values))[log->offset] = (long long)value;
|
||||||
((char **)(log->values))[log->offset] = (char *)value;
|
break;
|
||||||
break;
|
case ML_STRING:
|
||||||
}
|
((char **)(log->values))[log->offset] = (char *)value;
|
||||||
log->offset++;
|
break;
|
||||||
if (log->offset == log->size)
|
}
|
||||||
{
|
log->offset++;
|
||||||
if ((log->flags & MLNOAUTOFLUSH) == 0)
|
if (log->offset == log->size)
|
||||||
memlog_flush(log);
|
{
|
||||||
log->offset = 0;
|
if ((log->flags & MLNOAUTOFLUSH) == 0)
|
||||||
log->iflags = MLWRAPPED;
|
{
|
||||||
}
|
memlog_flush(log);
|
||||||
spinlock_release(&log->lock);
|
}
|
||||||
|
log->offset = 0;
|
||||||
|
log->iflags = MLWRAPPED;
|
||||||
|
}
|
||||||
|
spinlock_release(&log->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,30 +176,30 @@ memlog_log(MEMLOG *log, void *value)
|
|||||||
void
|
void
|
||||||
memlog_flush_all()
|
memlog_flush_all()
|
||||||
{
|
{
|
||||||
MEMLOG *log;
|
MEMLOG *log;
|
||||||
|
|
||||||
spinlock_acquire(&memlock);
|
spinlock_acquire(&memlock);
|
||||||
log = memlogs;
|
log = memlogs;
|
||||||
while (log)
|
while (log)
|
||||||
{
|
{
|
||||||
spinlock_acquire(&log->lock);
|
spinlock_acquire(&log->lock);
|
||||||
memlog_flush(log);
|
memlog_flush(log);
|
||||||
spinlock_release(&log->lock);
|
spinlock_release(&log->lock);
|
||||||
log = log->next;
|
log = log->next;
|
||||||
}
|
}
|
||||||
spinlock_release(&memlock);
|
spinlock_release(&memlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the flags for a memlog
|
* Set the flags for a memlog
|
||||||
*
|
*
|
||||||
* @param log The memlog to set the flags for
|
* @param log The memlog to set the flags for
|
||||||
* @param flags The new flags values
|
* @param flags The new flags values
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
memlog_set(MEMLOG *log, unsigned int flags)
|
memlog_set(MEMLOG *log, unsigned int flags)
|
||||||
{
|
{
|
||||||
log->flags = flags;
|
log->flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,63 +207,65 @@ memlog_set(MEMLOG *log, unsigned int flags)
|
|||||||
*
|
*
|
||||||
* Assumes the the log->lock has been acquired by the caller
|
* Assumes the the log->lock has been acquired by the caller
|
||||||
*
|
*
|
||||||
* @param log The memory log to flush
|
* @param log The memory log to flush
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
memlog_flush(MEMLOG *log)
|
memlog_flush(MEMLOG *log)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((fp = fopen(log->name, "a")) == NULL)
|
if ((fp = fopen(log->name, "a")) == NULL)
|
||||||
return;
|
{
|
||||||
if ((log->flags & MLNOAUTOFLUSH) && (log->iflags & MLWRAPPED))
|
return;
|
||||||
{
|
}
|
||||||
for (i = 0; i < log->size; i++)
|
if ((log->flags & MLNOAUTOFLUSH) && (log->iflags & MLWRAPPED))
|
||||||
{
|
{
|
||||||
int ind = (i + log->offset) % log->size;
|
for (i = 0; i < log->size; i++)
|
||||||
switch (log->type)
|
{
|
||||||
{
|
int ind = (i + log->offset) % log->size;
|
||||||
case ML_INT:
|
switch (log->type)
|
||||||
fprintf(fp, "%d\n",
|
{
|
||||||
((int *)(log->values))[ind]);
|
case ML_INT:
|
||||||
break;
|
fprintf(fp, "%d\n",
|
||||||
case ML_LONG:
|
((int *)(log->values))[ind]);
|
||||||
fprintf(fp, "%ld\n",
|
break;
|
||||||
((long *)(log->values))[ind]);
|
case ML_LONG:
|
||||||
break;
|
fprintf(fp, "%ld\n",
|
||||||
case ML_LONGLONG:
|
((long *)(log->values))[ind]);
|
||||||
fprintf(fp, "%lld\n",
|
break;
|
||||||
((long long *)(log->values))[ind]);
|
case ML_LONGLONG:
|
||||||
break;
|
fprintf(fp, "%lld\n",
|
||||||
case ML_STRING:
|
((long long *)(log->values))[ind]);
|
||||||
fprintf(fp, "%s\n",
|
break;
|
||||||
((char **)(log->values))[ind]);
|
case ML_STRING:
|
||||||
break;
|
fprintf(fp, "%s\n",
|
||||||
}
|
((char **)(log->values))[ind]);
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
for (i = 0; i < log->offset; i++)
|
else
|
||||||
{
|
{
|
||||||
switch (log->type)
|
for (i = 0; i < log->offset; i++)
|
||||||
{
|
{
|
||||||
case ML_INT:
|
switch (log->type)
|
||||||
fprintf(fp, "%d\n", ((int *)(log->values))[i]);
|
{
|
||||||
break;
|
case ML_INT:
|
||||||
case ML_LONG:
|
fprintf(fp, "%d\n", ((int *)(log->values))[i]);
|
||||||
fprintf(fp, "%ld\n", ((long *)(log->values))[i]);
|
break;
|
||||||
break;
|
case ML_LONG:
|
||||||
case ML_LONGLONG:
|
fprintf(fp, "%ld\n", ((long *)(log->values))[i]);
|
||||||
fprintf(fp, "%lld\n", ((long long *)(log->values))[i]);
|
break;
|
||||||
break;
|
case ML_LONGLONG:
|
||||||
case ML_STRING:
|
fprintf(fp, "%lld\n", ((long long *)(log->values))[i]);
|
||||||
fprintf(fp, "%s\n", ((char **)(log->values))[i]);
|
break;
|
||||||
break;
|
case ML_STRING:
|
||||||
}
|
fprintf(fp, "%s\n", ((char **)(log->values))[i]);
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
log->offset = 0;
|
}
|
||||||
fclose(fp);
|
}
|
||||||
|
log->offset = 0;
|
||||||
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,8 +24,8 @@
|
|||||||
* @verbatim
|
* @verbatim
|
||||||
* Revision History
|
* Revision History
|
||||||
*
|
*
|
||||||
* Date Who Description
|
* Date Who Description
|
||||||
* 26/09/14 Mark Riddoch Initial implementation
|
* 26/09/14 Mark Riddoch Initial implementation
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -33,33 +33,35 @@
|
|||||||
|
|
||||||
typedef enum { ML_INT, ML_LONG, ML_LONGLONG, ML_STRING } MEMLOGTYPE;
|
typedef enum { ML_INT, ML_LONG, ML_LONGLONG, ML_STRING } MEMLOGTYPE;
|
||||||
|
|
||||||
typedef struct memlog {
|
typedef struct memlog
|
||||||
char *name;
|
{
|
||||||
SPINLOCK lock;
|
char *name;
|
||||||
void *values;
|
SPINLOCK lock;
|
||||||
int offset;
|
void *values;
|
||||||
int size;
|
int offset;
|
||||||
MEMLOGTYPE type;
|
int size;
|
||||||
unsigned int flags;
|
MEMLOGTYPE type;
|
||||||
unsigned int iflags;
|
unsigned int flags;
|
||||||
struct memlog *next;
|
unsigned int iflags;
|
||||||
|
struct memlog *next;
|
||||||
} MEMLOG;
|
} MEMLOG;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MEMLOG flag bits
|
* MEMLOG flag bits
|
||||||
*/
|
*/
|
||||||
#define MLNOAUTOFLUSH 0x0001
|
#define MLNOAUTOFLUSH 0x0001
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MEMLOG internal flags
|
* MEMLOG internal flags
|
||||||
*/
|
*/
|
||||||
#define MLWRAPPED 0x0001
|
#define MLWRAPPED 0x0001
|
||||||
|
|
||||||
|
|
||||||
extern MEMLOG *memlog_create(char *, MEMLOGTYPE, int);
|
extern MEMLOG *memlog_create(char *, MEMLOGTYPE, int);
|
||||||
extern void memlog_destroy(MEMLOG *);
|
extern void memlog_destroy(MEMLOG *);
|
||||||
extern void memlog_set(MEMLOG *, unsigned int);
|
extern void memlog_set(MEMLOG *, unsigned int);
|
||||||
extern void memlog_log(MEMLOG *, void *);
|
extern void memlog_log(MEMLOG *, void *);
|
||||||
extern void memlog_flush_all();
|
extern void memlog_flush_all();
|
||||||
extern void memlog_flush(MEMLOG *);
|
extern void memlog_flush(MEMLOG *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user