Reindented server/core/memlog.c

This commit is contained in:
Johan Wikman
2015-11-30 14:15:15 +02:00
parent 60fb05ea40
commit 72dd159f98
2 changed files with 196 additions and 180 deletions

View File

@ -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);
} }

View File

@ -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