util/queue: fix a data race detected by TSAN when finishing the queue

Thread sanitizer complains if it detects that the pthread_barrier
is destroyed when a thread might still blocked on the barrier.

Fix this by destroying the barrier only if pthread_barrier_wait
returns PTHREAD_BARRIER_SERIAL_THREAD which is the value for success.

In practice this shouldn't fix anything serious given that this code
is only called when the disk cache is destroyed.

Original patch from Timothy Arceri.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4342
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13861>
This commit is contained in:
Samuel Pitoiset 2021-11-18 16:58:42 +01:00
parent cee1dd92bd
commit 04c90f292e
2 changed files with 7 additions and 6 deletions

View file

@ -527,7 +527,8 @@ static void
util_queue_finish_execute(void *data, void *gdata, int num_thread)
{
util_barrier *barrier = data;
util_barrier_wait(barrier);
if (util_barrier_wait(barrier))
util_barrier_destroy(barrier);
}
void
@ -705,8 +706,6 @@ util_queue_finish(struct util_queue *queue)
}
simple_mtx_unlock(&queue->finish_lock);
util_barrier_destroy(&barrier);
free(fences);
}

View file

@ -296,9 +296,9 @@ static inline void util_barrier_destroy(util_barrier *barrier)
pthread_barrier_destroy(barrier);
}
static inline void util_barrier_wait(util_barrier *barrier)
static inline bool util_barrier_wait(util_barrier *barrier)
{
pthread_barrier_wait(barrier);
return pthread_barrier_wait(barrier) == PTHREAD_BARRIER_SERIAL_THREAD;
}
@ -328,7 +328,7 @@ static inline void util_barrier_destroy(util_barrier *barrier)
cnd_destroy(&barrier->condvar);
}
static inline void util_barrier_wait(util_barrier *barrier)
static inline bool util_barrier_wait(util_barrier *barrier)
{
mtx_lock(&barrier->mutex);
@ -348,6 +348,8 @@ static inline void util_barrier_wait(util_barrier *barrier)
}
mtx_unlock(&barrier->mutex);
return true;
}
#endif