all repos — mgba @ 00dd5bdaa81e97f46474f527443e8cf07f6e1ae9

mGBA Game Boy Advance Emulator

Dual condition-variable non-hacky waiting-on-frame
Jeffrey Pfau jeffrey@endrift.com
Wed, 24 Apr 2013 02:43:55 -0700
commit

00dd5bdaa81e97f46474f527443e8cf07f6e1ae9

parent

5122a236e0cb6ed73a274584b94d0639bf0157f3

3 files changed, 23 insertions(+), 8 deletions(-)

jump to
M src/gba/renderers/video-software.csrc/gba/renderers/video-software.c

@@ -46,7 +46,8 @@ {

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; renderer->mutex = mutex; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - renderer->cond = cond; + renderer->upCond = cond; + renderer->downCond = cond; } }

@@ -93,14 +94,16 @@ bg->sy = 0;

} pthread_mutex_init(&softwareRenderer->mutex, 0); - pthread_cond_init(&softwareRenderer->cond, 0); + pthread_cond_init(&softwareRenderer->upCond, 0); + pthread_cond_init(&softwareRenderer->downCond, 0); } static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; pthread_mutex_destroy(&softwareRenderer->mutex); - pthread_cond_destroy(&softwareRenderer->cond); + pthread_cond_destroy(&softwareRenderer->upCond); + pthread_cond_destroy(&softwareRenderer->downCond); } static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {

@@ -210,8 +213,9 @@ struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;

pthread_mutex_lock(&softwareRenderer->mutex); renderer->framesPending++; + pthread_cond_broadcast(&softwareRenderer->upCond); if (!renderer->turbo) { - pthread_cond_wait(&softwareRenderer->cond, &softwareRenderer->mutex); + pthread_cond_wait(&softwareRenderer->downCond, &softwareRenderer->mutex); } pthread_mutex_unlock(&softwareRenderer->mutex); }
M src/gba/renderers/video-software.hsrc/gba/renderers/video-software.h

@@ -71,7 +71,8 @@

uint16_t* row; pthread_mutex_t mutex; - pthread_cond_t cond; + pthread_cond_t upCond; + pthread_cond_t downCond; }; void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer);
M src/main.csrc/main.c

@@ -9,6 +9,7 @@

#include <fcntl.h> #include <errno.h> #include <signal.h> +#include <sys/time.h> #include <unistd.h> struct GLSoftwareRenderer {

@@ -118,12 +119,21 @@ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

SDL_GL_SwapBuffers(); pthread_mutex_lock(&renderer->d.mutex); - pthread_cond_broadcast(&renderer->d.cond); + pthread_cond_broadcast(&renderer->d.downCond); pthread_mutex_unlock(&renderer->d.mutex); } else { + while (!renderer->d.d.framesPending) { + struct timeval tv; + struct timespec ts; + gettimeofday(&tv, 0); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000 + 800000; + int err = pthread_cond_timedwait(&renderer->d.upCond, &renderer->d.mutex, &ts); + if (err == ETIMEDOUT) { + break; + } + } pthread_mutex_unlock(&renderer->d.mutex); - // We have no frame, let's just wait a sec to see if we get one. - usleep(500); } while (SDL_PollEvent(&event)) { switch (event.type) {