all repos — mgba @ ad7cb650dce79b8155be65663e37c337d8e67a71

mGBA Game Boy Advance Emulator

Core: Add logging filters
Vicki Pfau vi@endrift.com
Sun, 05 Mar 2017 17:25:35 -0800
commit

ad7cb650dce79b8155be65663e37c337d8e67a71

parent

3c0c8a8f54a4798e61dd3a67645e91b91d2b0725

4 files changed, 101 insertions(+), 11 deletions(-)

jump to
M include/mgba/core/log.hinclude/mgba/core/log.h

@@ -10,6 +10,8 @@ #include <mgba-util/common.h>

CXX_GUARD_START +#include <mgba-util/table.h> + enum mLogLevel { mLOG_FATAL = 0x01, mLOG_ERROR = 0x02,

@@ -20,10 +22,18 @@ mLOG_STUB = 0x20,

mLOG_GAME_ERROR = 0x40, mLOG_ALL = 0x7F +}; + +struct Table; +struct mLogFilter { + int defaultLevels; + struct Table categories; + struct Table levels; }; struct mLogger { void (*log)(struct mLogger*, int category, enum mLogLevel level, const char* format, va_list args); + struct mLogFilter* filter; }; struct mLogger* mLogGetContext(void);

@@ -32,6 +42,13 @@ int mLogGenerateCategory(const char*, const char*);

const char* mLogCategoryName(int); const char* mLogCategoryId(int); int mLogCategoryById(const char*); + +struct mCoreConfig; +void mLogFilterInit(struct mLogFilter*); +void mLogFilterDeinit(struct mLogFilter*); +void mLogFilterLoad(struct mLogFilter*, const struct mCoreConfig*); +void mLogFilterSet(struct mLogFilter*, const char* category, int levels); +bool mLogFilterTest(struct mLogFilter*, int category, enum mLogLevel level); ATTRIBUTE_FORMAT(printf, 3, 4) void mLog(int category, enum mLogLevel level, const char* format, ...);
M include/mgba/core/thread.hinclude/mgba/core/thread.h

@@ -58,7 +58,6 @@ int interruptDepth;

bool frameWasOn; struct mThreadLogger logger; - enum mLogLevel logLevel; ThreadCallback startCallback; ThreadCallback resetCallback; ThreadCallback cleanCallback;
M src/core/log.csrc/core/log.c

@@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this

* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include <mgba/core/log.h> +#include <mgba/core/config.h> #include <mgba/core/thread.h> #define MAX_CATEGORY 64

@@ -36,7 +37,7 @@ _categoryNames[_category] = name;

_categoryIds[_category] = id; } ++_category; - return _category; + return _category - 1; } const char* mLogCategoryName(int category) {

@@ -68,13 +69,78 @@ struct mLogger* context = mLogGetContext();

va_list args; va_start(args, format); if (context) { - context->log(context, category, level, format, args); + if (!context->filter || mLogFilterTest(context->filter, category, level)) { + context->log(context, category, level, format, args); + } } else { printf("%s: ", mLogCategoryName(category)); vprintf(format, args); printf("\n"); } va_end(args); +} + +void mLogFilterInit(struct mLogFilter* filter) { + HashTableInit(&filter->categories, 8, NULL); + TableInit(&filter->levels, 8, NULL); +} + +void mLogFilterDeinit(struct mLogFilter* filter) { + HashTableDeinit(&filter->categories); + TableDeinit(&filter->levels); +} + +static void _setFilterLevel(const char* key, const char* value, enum mCoreConfigLevel level, void* user) { + UNUSED(level); + struct mLogFilter* filter = user; + key = strchr(key, '.'); + if (!key || !key[1]) { + return; + } + if (!value) { + return; + } + ++key; + char* end; + int ivalue = strtol(value, &end, 10); + if (ivalue == 0) { + ivalue = INT_MIN; // Zero is reserved + } + if (!end) { + return; + } + mLogFilterSet(filter, key, ivalue); +} + +void mLogFilterLoad(struct mLogFilter* filter, const struct mCoreConfig* config) { + mCoreConfigEnumerate(config, "logLevel.", _setFilterLevel, filter); + filter->defaultLevels = mLOG_ALL; + mCoreConfigGetIntValue(config, "logLevel", &filter->defaultLevels); +} + +void mLogFilterSet(struct mLogFilter* filter, const char* category, int levels) { + HashTableInsert(&filter->categories, category, (void*)(intptr_t) levels); + // Can't do this eagerly because not all categories are initialized immediately + int cat = mLogCategoryById(category); + if (cat >= 0) { + TableInsert(&filter->levels, cat, (void*)(intptr_t) levels); + } + +} +bool mLogFilterTest(struct mLogFilter* filter, int category, enum mLogLevel level) { + int value = (int) TableLookup(&filter->levels, category); + if (value) { + return value & level; + } + const char* cat = mLogCategoryId(category); + if (cat) { + value = (int) HashTableLookup(&filter->categories, cat); + if (value) { + TableInsert(&filter->levels, category, (void*)(intptr_t) value); + return value & level; + } + } + return level & filter->defaultLevels; } mLOG_DEFINE_CATEGORY(STATUS, "Status", "core.status")
M src/core/thread.csrc/core/thread.c

@@ -36,6 +36,8 @@ return TRUE;

} #endif +static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args); + static void _changeState(struct mCoreThread* threadContext, enum mCoreThreadState newState, bool broadcast) { MutexLock(&threadContext->stateMutex); threadContext->state = newState;

@@ -147,6 +149,13 @@ core->addCoreCallbacks(core, &callbacks);

core->setSync(core, &threadContext->sync); core->reset(core); + struct mLogFilter filter; + if (!threadContext->logger.d.filter) { + threadContext->logger.d.filter = &filter; + mLogFilterInit(threadContext->logger.d.filter); + mLogFilterLoad(threadContext->logger.d.filter, &core->config); + } + if (core->opts.rewindEnable && core->opts.rewindBufferCapacity > 0) { mCoreRewindContextInit(&threadContext->rewind, core->opts.rewindBufferCapacity); threadContext->rewind.stateFlags = core->opts.rewindSave ? SAVESTATE_SAVEDATA : 0;

@@ -225,13 +234,18 @@ threadContext->cleanCallback(threadContext);

} core->clearCoreCallbacks(core); + threadContext->logger.d.filter = NULL; + return 0; } bool mCoreThreadStart(struct mCoreThread* threadContext) { threadContext->state = THREAD_INITIALIZED; threadContext->logger.p = threadContext; - threadContext->logLevel = threadContext->core->opts.logLevel; + if (!threadContext->logger.d.log) { + threadContext->logger.d.log = _mCoreLog; + threadContext->logger.d.filter = NULL; + } if (!threadContext->sync.fpsTarget) { threadContext->sync.fpsTarget = _defaultFPSTarget;

@@ -544,10 +558,7 @@ #endif

static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) { UNUSED(logger); - struct mCoreThread* thread = mCoreThreadGet(); - if (thread && !(thread->logLevel & level)) { - return; - } + UNUSED(level); printf("%s: ", mLogCategoryName(category)); vprintf(format, args); printf("\n");

@@ -556,9 +567,6 @@

struct mLogger* mCoreThreadLogger(void) { struct mCoreThread* thread = mCoreThreadGet(); if (thread) { - if (!thread->logger.d.log) { - thread->logger.d.log = _mCoreLog; - } return &thread->logger.d; } return NULL;