Core: Fix up thread proxy waiting
Vicki Pfau vi@endrift.com
Sun, 23 Sep 2018 13:26:52 -0700
6 files changed,
20 insertions(+),
6 deletions(-)
M
include/mgba-util/ring-fifo.h
→
include/mgba-util/ring-fifo.h
@@ -20,6 +20,7 @@
void RingFIFOInit(struct RingFIFO* buffer, size_t capacity); void RingFIFODeinit(struct RingFIFO* buffer); size_t RingFIFOCapacity(const struct RingFIFO* buffer); +size_t RingFIFOSize(const struct RingFIFO* buffer); void RingFIFOClear(struct RingFIFO* buffer); size_t RingFIFOWrite(struct RingFIFO* buffer, const void* value, size_t length); size_t RingFIFORead(struct RingFIFO* buffer, void* output, size_t length);
M
src/feature/thread-proxy.c
→
src/feature/thread-proxy.c
@@ -121,7 +121,7 @@ read = RingFIFORead(&proxyRenderer->dirtyQueue, data, length);
if (!block || read) { break; } - mLOG(GBA_VIDEO, DEBUG, "Proxy thread can't read VRAM. CPU thread asleep?"); + mLOG(GBA_VIDEO, DEBUG, "Can't read %"PRIz"u bytes. CPU thread asleep?", length); MutexLock(&proxyRenderer->mutex); ConditionWake(&proxyRenderer->fromThreadCond); ConditionWait(&proxyRenderer->toThreadCond, &proxyRenderer->mutex);@@ -142,7 +142,7 @@ mLOG(GBA_VIDEO, ERROR, "Proxy thread stopped prematurely!");
_proxyThreadRecover(proxyRenderer); return; } - while (proxyRenderer->threadState == PROXY_THREAD_BUSY) { + while (RingFIFOSize(&proxyRenderer->dirtyQueue)) { ConditionWake(&proxyRenderer->toThreadCond); ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex); }
M
src/feature/video-logger.c
→
src/feature/video-logger.c
@@ -258,6 +258,9 @@ 0,
0xDEADBEEF, }; logger->writeData(logger, &dirty, sizeof(dirty)); + if (logger->wait) { + logger->wait(logger); + } } void mVideoLoggerRendererFinishFrame(struct mVideoLogger* logger) {
M
src/gb/extra/proxy.c
→
src/gb/extra/proxy.c
@@ -252,7 +252,6 @@ void GBVideoProxyRendererFinishFrame(struct GBVideoRenderer* renderer) {
struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { proxyRenderer->logger->lock(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } if (!proxyRenderer->logger->block) { proxyRenderer->backend->finishFrame(proxyRenderer->backend);
M
src/gba/extra/proxy.c
→
src/gba/extra/proxy.c
@@ -146,6 +146,8 @@ case DIRTY_VRAM:
if (item->address <= SIZE_VRAM - 0x1000) { logger->readData(logger, &logger->vram[item->address >> 1], 0x1000, true); proxyRenderer->backend->writeVRAM(proxyRenderer->backend, item->address); + } else { + logger->readData(logger, NULL, 0x1000, true); } break; case DIRTY_SCANLINE:@@ -250,7 +252,6 @@ void GBAVideoProxyRendererFinishFrame(struct GBAVideoRenderer* renderer) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { proxyRenderer->logger->lock(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } if (!proxyRenderer->logger->block) { proxyRenderer->backend->finishFrame(proxyRenderer->backend);@@ -268,7 +269,6 @@ if (proxyRenderer->logger->block && proxyRenderer->logger->wait) {
proxyRenderer->logger->lock(proxyRenderer->logger); // Insert an extra item into the queue to make sure it gets flushed mVideoLoggerRendererFlush(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels); if (proxyRenderer->logger->block && proxyRenderer->logger->wait) {@@ -282,7 +282,6 @@ if (proxyRenderer->logger->block && proxyRenderer->logger->wait) {
proxyRenderer->logger->lock(proxyRenderer->logger); // Insert an extra item into the queue to make sure it gets flushed mVideoLoggerRendererFlush(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } proxyRenderer->backend->putPixels(proxyRenderer->backend, stride, pixels); if (proxyRenderer->logger->block && proxyRenderer->logger->wait) {
M
src/util/ring-fifo.c
→
src/util/ring-fifo.c
@@ -22,6 +22,18 @@ size_t RingFIFOCapacity(const struct RingFIFO* buffer) {
return buffer->capacity; } +size_t RingFIFOSize(const struct RingFIFO* buffer) { + const void* read; + const void* write; + ATOMIC_LOAD(read, buffer->readPtr); + ATOMIC_LOAD(write, buffer->readPtr); + if (read <= write) { + return (uintptr_t) write - (uintptr_t) read; + } else { + return buffer->capacity - (uintptr_t) read + (uintptr_t) write; + } +} + void RingFIFOClear(struct RingFIFO* buffer) { ATOMIC_STORE(buffer->readPtr, buffer->data); ATOMIC_STORE(buffer->writePtr, buffer->data);