ipc: Avoid deadlocks due to render timing helper not getting data in time

This commit is contained in:
Jakob Bornecrantz 2020-07-01 13:22:03 +01:00
parent addeea2acf
commit 5bad87690f
4 changed files with 22 additions and 13 deletions

View file

@ -39,6 +39,7 @@ get_last_input_plus_period_at_least_greater_then(struct u_rt_helper *urth,
while (val <= then_ns) {
val += urth->period;
assert(val != 0);
}
return val;
@ -52,10 +53,8 @@ get_last_input_plus_period_at_least_greater_then(struct u_rt_helper *urth,
*/
void
u_rt_helper_clear(struct u_rt_helper *urth)
u_rt_helper_client_clear(struct u_rt_helper *urth)
{
U_ZERO(urth);
for (size_t i = 0; i < ARRAY_SIZE(urth->frames); i++) {
urth->frames[i].state = U_RT_READY;
urth->frames[i].frame_id = -1;
@ -65,7 +64,8 @@ u_rt_helper_clear(struct u_rt_helper *urth)
void
u_rt_helper_init(struct u_rt_helper *urth)
{
u_rt_helper_clear(urth);
U_ZERO(urth);
u_rt_helper_client_clear(urth);
}
void

View file

@ -52,8 +52,12 @@ struct u_rt_helper
void
u_rt_helper_init(struct u_rt_helper *urth);
/*!
* This function gets the client part of the render timing helper ready to be
* used. If you use init you will also clear all of the timing information.
*/
void
u_rt_helper_clear(struct u_rt_helper *urth);
u_rt_helper_client_clear(struct u_rt_helper *urth);
void
u_rt_helper_predict(struct u_rt_helper *urth,

View file

@ -524,7 +524,8 @@ client_loop(volatile struct ipc_client_state *ics)
{
fprintf(stderr, "SERVER: Client connected\n");
u_rt_helper_init((struct u_rt_helper *)&ics->urth);
// Make sure it's ready for the client.
u_rt_helper_client_clear((struct u_rt_helper *)&ics->urth);
// Claim the client fd.
int epoll_fd = setup_epoll(ics->ipc_socket_fd);
@ -591,7 +592,8 @@ client_loop(volatile struct ipc_client_state *ics)
close(ics->ipc_socket_fd);
ics->ipc_socket_fd = -1;
u_rt_helper_clear((struct u_rt_helper *)&ics->urth);
// Reset the urth for the next client.
u_rt_helper_client_clear((struct u_rt_helper *)&ics->urth);
ics->num_swapchains = 0;

View file

@ -432,6 +432,11 @@ init_all(struct ipc_server *s)
return ret;
}
// Init all of the render riming helpers.
for (size_t i = 0; i < ARRAY_SIZE(s->threads); i++) {
u_rt_helper_init((struct u_rt_helper *)&s->threads[i].ics.urth);
}
ret = os_mutex_init(&s->global_state_lock);
if (ret < 0) {
teardown_all(s);
@ -749,12 +754,6 @@ main_loop(struct ipc_server *s)
// compositor and consistent initial state
while (s->running) {
/*
* Check polling.
*/
check_epoll(s);
int64_t frame_id;
uint64_t predicted_display_time;
uint64_t predicted_display_period;
@ -777,12 +776,16 @@ main_loop(struct ipc_server *s)
os_mutex_unlock(&s->global_state_lock);
xrt_comp_begin_frame(xc, frame_id);
xrt_comp_layer_begin(xc, frame_id, 0);
_update_layers(s, xc);
xrt_comp_layer_commit(xc, frame_id);
// Check polling last, so we know we have valid timing data.
check_epoll(s);
}
return 0;