Fix potential deadlock issue in multithreaded modules When a thread encounters an error, it will invoke the respective sync_write() function to set the num_finished_cols[r] of every row to a maximum column number in order to avoid dependent workers waiting indefinitely. This maximum column number can be overwritten by a non-erroneous thread with a lower column number causing the dependent worker to wait indefinitely. This CL resolves this issue by modifying the respective sync_write() functions such that they will never decrease the num_finished_cols[r]. Bug: aomedia:3276 Change-Id: I1686a9d4d8b61fbca8387b9ca2e14de689f8d56c
diff --git a/av1/common/thread_common.c b/av1/common/thread_common.c index 7dafb9a..1b33a9a 100644 --- a/av1/common/thread_common.c +++ b/av1/common/thread_common.c
@@ -233,7 +233,12 @@ if (sig) { pthread_mutex_lock(&lf_sync->mutex_[plane][r]); - lf_sync->cur_sb_col[plane][r] = cur; + // When a thread encounters an error, cur_sb_col[plane][r] is set to maximum + // column number. In this case, the AOMMAX operation here ensures that + // cur_sb_col[plane][r] is not overwritten with a smaller value thus + // preventing the infinite waiting of threads in the relevant sync_read() + // function. + lf_sync->cur_sb_col[plane][r] = AOMMAX(lf_sync->cur_sb_col[plane][r], cur); pthread_cond_broadcast(&lf_sync->cond_[plane][r]); pthread_mutex_unlock(&lf_sync->mutex_[plane][r]); @@ -550,7 +555,13 @@ if (sig) { pthread_mutex_lock(&loop_res_sync->mutex_[plane][r]); - loop_res_sync->cur_sb_col[plane][r] = cur; + // When a thread encounters an error, cur_sb_col[plane][r] is set to maximum + // column number. In this case, the AOMMAX operation here ensures that + // cur_sb_col[plane][r] is not overwritten with a smaller value thus + // preventing the infinite waiting of threads in the relevant sync_read() + // function. + loop_res_sync->cur_sb_col[plane][r] = + AOMMAX(loop_res_sync->cur_sb_col[plane][r], cur); pthread_cond_broadcast(&loop_res_sync->cond_[plane][r]); pthread_mutex_unlock(&loop_res_sync->mutex_[plane][r]);
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c index 61bb8a2..8bf73e7 100644 --- a/av1/encoder/ethread.c +++ b/av1/encoder/ethread.c
@@ -2082,7 +2082,13 @@ if (sig) { pthread_mutex_lock(&tpl_row_mt_sync->mutex_[r]); - tpl_row_mt_sync->num_finished_cols[r] = cur; + // When a thread encounters an error, num_finished_cols[r] is set to maximum + // column number. In this case, the AOMMAX operation here ensures that + // num_finished_cols[r] is not overwritten with a smaller value thus + // preventing the infinite waiting of threads in the relevant sync_read() + // function. + tpl_row_mt_sync->num_finished_cols[r] = + AOMMAX(tpl_row_mt_sync->num_finished_cols[r], cur); pthread_cond_signal(&tpl_row_mt_sync->cond_[r]); pthread_mutex_unlock(&tpl_row_mt_sync->mutex_[r]);