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

View file

@ -52,8 +52,12 @@ struct u_rt_helper
void void
u_rt_helper_init(struct u_rt_helper *urth); 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 void
u_rt_helper_clear(struct u_rt_helper *urth); u_rt_helper_client_clear(struct u_rt_helper *urth);
void void
u_rt_helper_predict(struct u_rt_helper *urth, 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"); 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. // Claim the client fd.
int epoll_fd = setup_epoll(ics->ipc_socket_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); close(ics->ipc_socket_fd);
ics->ipc_socket_fd = -1; 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; ics->num_swapchains = 0;

View file

@ -432,6 +432,11 @@ init_all(struct ipc_server *s)
return ret; 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); ret = os_mutex_init(&s->global_state_lock);
if (ret < 0) { if (ret < 0) {
teardown_all(s); teardown_all(s);
@ -749,12 +754,6 @@ main_loop(struct ipc_server *s)
// compositor and consistent initial state // compositor and consistent initial state
while (s->running) { while (s->running) {
/*
* Check polling.
*/
check_epoll(s);
int64_t frame_id; int64_t frame_id;
uint64_t predicted_display_time; uint64_t predicted_display_time;
uint64_t predicted_display_period; uint64_t predicted_display_period;
@ -777,12 +776,16 @@ main_loop(struct ipc_server *s)
os_mutex_unlock(&s->global_state_lock); os_mutex_unlock(&s->global_state_lock);
xrt_comp_begin_frame(xc, frame_id); xrt_comp_begin_frame(xc, frame_id);
xrt_comp_layer_begin(xc, frame_id, 0); xrt_comp_layer_begin(xc, frame_id, 0);
_update_layers(s, xc); _update_layers(s, xc);
xrt_comp_layer_commit(xc, frame_id); xrt_comp_layer_commit(xc, frame_id);
// Check polling last, so we know we have valid timing data.
check_epoll(s);
} }
return 0; return 0;