Avoid potential dispmanx_gfx driver lockup

The dispmanx driver had a small race wherein if the vsync completed
between checking for a free page and waiting on the condvar, it would
hang forever waiting for a condition that would never fire.

I'm hoping this is what was causing the triple buffering lockups. In
my testing with it re-enabled and this fix, things are stable (and
much more performant than with triple buffering disabled).
This commit is contained in:
Andrew 2017-04-28 20:24:36 -07:00
parent 253c8cd997
commit 301a094ef9

View File

@ -104,7 +104,6 @@ struct dispmanx_video
/* For threading */
scond_t *vsync_condition;
slock_t *vsync_cond_mutex;
slock_t *pending_mutex;
unsigned int pageflip_pending;
@ -152,9 +151,10 @@ static struct dispmanx_page *dispmanx_get_free_page(void *data, struct dispmanx_
* wait until a free page is freed by vsync CB. */
if (!page)
{
slock_lock(_dispvars->vsync_cond_mutex);
scond_wait(_dispvars->vsync_condition, _dispvars->vsync_cond_mutex);
slock_unlock(_dispvars->vsync_cond_mutex);
slock_lock(_dispvars->pending_mutex);
if (_dispvars->pageflip_pending > 0)
scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
slock_unlock(_dispvars->pending_mutex);
}
}
@ -426,7 +426,6 @@ static void *dispmanx_gfx_init(const video_info_t *video,
/* Initialize the rest of the mutexes and conditions. */
_dispvars->vsync_condition = scond_new();
_dispvars->vsync_cond_mutex = slock_new();
_dispvars->pending_mutex = slock_new();
_dispvars->core_width = 0;
_dispvars->core_height = 0;
@ -697,7 +696,6 @@ static void dispmanx_gfx_free(void *data)
/* Destroy mutexes and conditions. */
slock_free(_dispvars->pending_mutex);
slock_free(_dispvars->vsync_cond_mutex);
scond_free(_dispvars->vsync_condition);
free(_dispvars);