Added the ability to have a non-auto-flushing memlog. Flush is then a

manual process. Useful for triggering the dumping of the circular buffer when
an error is detected.
This commit is contained in:
Mark Riddoch
2014-10-14 11:40:23 +01:00
parent 8986a8042e
commit 52e8b33422
2 changed files with 76 additions and 19 deletions

View File

@ -33,8 +33,6 @@
static MEMLOG *memlogs = NULL; static MEMLOG *memlogs = NULL;
static SPINLOCK *memlock = SPINLOCK_INIT; static SPINLOCK *memlock = SPINLOCK_INIT;
static void memlog_flush(MEMLOG *);
/** /**
* Create a new instance of a memory logger. * Create a new instance of a memory logger.
* *
@ -59,6 +57,7 @@ MEMLOG *log;
log->type = type; log->type = type;
log->offset = 0; log->offset = 0;
log->size = size; log->size = size;
log->flags = 0;
switch (type) switch (type)
{ {
case ML_INT: case ML_INT:
@ -97,6 +96,7 @@ memlog_destroy(MEMLOG *log)
{ {
MEMLOG *ptr; MEMLOG *ptr;
if ((log->flags & MLNOAUTOFLUSH) == 0)
memlog_flush(log); memlog_flush(log);
free(log->values); free(log->values);
@ -146,8 +146,10 @@ memlog_log(MEMLOG *log, void *value)
log->offset++; log->offset++;
if (log->offset == log->size) if (log->offset == log->size)
{ {
if ((log->flags & MLNOAUTOFLUSH) == 0)
memlog_flush(log); memlog_flush(log);
log->offset = 0; log->offset = 0;
log->iflags = MLWRAPPED;
} }
spinlock_release(&log->lock); spinlock_release(&log->lock);
} }
@ -173,6 +175,17 @@ MEMLOG *log;
spinlock_release(&memlock); spinlock_release(&memlock);
} }
/**
* Set the flags for a memlog
*
* @param log The memlog to set the flags for
* @param flags The new flags values
*/
void
memlog_set(MEMLOG *log, unsigned int flags)
{
log->flags = flags;
}
/** /**
* Flush a memory log to disk * Flush a memory log to disk
@ -181,7 +194,7 @@ MEMLOG *log;
* *
* @param log The memory log to flush * @param log The memory log to flush
*/ */
static void void
memlog_flush(MEMLOG *log) memlog_flush(MEMLOG *log)
{ {
FILE *fp; FILE *fp;
@ -189,6 +202,34 @@ int i;
if ((fp = fopen(log->name, "a")) == NULL) if ((fp = fopen(log->name, "a")) == NULL)
return; return;
if ((log->flags & MLNOAUTOFLUSH) && (log->iflags & MLWRAPPED))
{
for (i = 0; i < log->size; i++)
{
int ind = (i + log->offset) % log->size;
switch (log->type)
{
case ML_INT:
fprintf(fp, "%d\n",
((int *)(log->values))[ind]);
break;
case ML_LONG:
fprintf(fp, "%ld\n",
((long *)(log->values))[ind]);
break;
case ML_LONGLONG:
fprintf(fp, "%lld\n",
((long long *)(log->values))[ind]);
break;
case ML_STRING:
fprintf(fp, "%s\n",
((char **)(log->values))[ind]);
break;
}
}
}
else
{
for (i = 0; i < log->offset; i++) for (i = 0; i < log->offset; i++)
{ {
switch (log->type) switch (log->type)
@ -207,5 +248,7 @@ int i;
break; break;
} }
} }
}
log->offset = 0;
fclose(fp); fclose(fp);
} }

View File

@ -40,12 +40,26 @@ typedef struct memlog {
int offset; int offset;
int size; int size;
MEMLOGTYPE type; MEMLOGTYPE type;
unsigned int flags;
unsigned int iflags;
struct memlog *next; struct memlog *next;
} MEMLOG; } MEMLOG;
/*
* MEMLOG flag bits
*/
#define MLNOAUTOFLUSH 0x0001
/*
* MEMLOG internal flags
*/
#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_log(MEMLOG *, void *); extern void memlog_log(MEMLOG *, void *);
extern void memlog_flush_all(); extern void memlog_flush_all();
extern void memlog_flush(MEMLOG *);
#endif #endif