[waffle] [PATCH v2 3/3] wcore_error_unittest: Fix race condition leading to forever loop
Chad Versace
chad.versace at linux.intel.com
Wed May 30 16:19:35 PDT 2012
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 05/30/2012 08:52 AM, Pauli Nieminen wrote:
> Reading non-volatile value in loop without function calls allows C
> compiler to generate forever loop without checking the memory value. To
> avoid the problem locking or atomic operations could be used.
>
> But there is better solution of using pthread_barrier_t that test case
> was trying to simulate with mutex and conditional. Barrier promises that
> all threads are released when requested number of threads are blocked in
> pthread_barrier_wait.
>
> Signed-off-by: Pauli Nieminen <pauli.nieminen at linux.intel.com>
> ---
> tests/unittests/waffle/core/wcore_error_unittest.c | 37 ++++----------------
> 1 file changed, 7 insertions(+), 30 deletions(-)
This patch is almost a revert of cc85550, in which I removed
pthread_barrier_t and emulated it with pthread_cond_t. Yes, pthread_barrier_t
is better pthread_cond_t, but MacOS 10.7 doesn't support barriers.
Is this the problematic loop that you are referring to?
while (num_threads_waiting < NUM_THREADS)
;;
>
> diff --git a/tests/unittests/waffle/core/wcore_error_unittest.c b/tests/unittests/waffle/core/wcore_error_unittest.c
> index 2a1f5c1..0098450 100644
> --- a/tests/unittests/waffle/core/wcore_error_unittest.c
> +++ b/tests/unittests/waffle/core/wcore_error_unittest.c
> @@ -131,13 +131,7 @@ struct thread_arg {
> int thread_id;
>
> /// Protects `num_threads_waiting` and `cond`.
> - pthread_mutex_t *mutex;
> -
> - /// Satisfied when `num_threads_waiting == TOTAL_THREADS`.
> - pthread_cond_t *cond;
> -
> - /// Number of threads waiting on `cond`.
> - int *num_threads_waiting;
> + pthread_barrier_t *barrier;
> };
>
> /// The start routine given to threads in test wcore_error.thread_local.
> @@ -159,13 +153,7 @@ thread_start(struct thread_arg *a)
> // Each thread sets its error code.
> wcore_error(error_code);
>
> - // Wait for all threads to set their error codes, thus giving
> - // the threads opportunity to clobber each other's codes.
> - pthread_mutex_lock(a->mutex); {
> - *a->num_threads_waiting += 1;
> - pthread_cond_wait(a->cond, a->mutex);
> - pthread_mutex_unlock(a->mutex);
> - }
> + pthread_barrier_wait(a->barrier);
>
> // Verify that the threads did not clobber each other's
> // error codes.
> @@ -177,23 +165,18 @@ thread_start(struct thread_arg *a)
> // Test that threads do not clobber each other's error codes.
> TEST(wcore_error, thread_local)
> {
> - pthread_mutex_t mutex;
> - pthread_cond_t cond;
> - int num_threads_waiting = 0;
> + pthread_barrier_t barrier;
>
> pthread_t threads[NUM_THREADS];
> struct thread_arg thread_args[NUM_THREADS];
> bool exit_codes[NUM_THREADS];
>
> - pthread_mutex_init(&mutex, NULL);
> - pthread_cond_init(&cond, NULL);
> + pthread_barrier_init(&barrier, NULL, NUM_THREADS + 1);
>
> for (intptr_t i = 0; i < NUM_THREADS; ++i) {
> struct thread_arg *a = &thread_args[i];
> a->thread_id = i;
> - a->mutex = &mutex;
> - a->cond = &cond;
> - a->num_threads_waiting = &num_threads_waiting;
> + a->barrier = &barrier;
>
> pthread_create(&threads[i], NULL,
> (void* (*)(void*)) thread_start,
> @@ -202,20 +185,14 @@ TEST(wcore_error, thread_local)
>
> // Wait for all threads to set their error codes, thus giving
> // the threads opportunity to clobber each other's codes.
> - while (num_threads_waiting < NUM_THREADS)
> - ;;
> - pthread_mutex_lock(&mutex); {
> - pthread_cond_broadcast(&cond);
> - pthread_mutex_unlock(&mutex);
> - }
> + pthread_barrier_wait(&barrier);
>
> for (int i = 0; i < NUM_THREADS; ++i) {
> pthread_join(threads[i], (void**) &exit_codes[i]);
> EXPECT_TRUE(exit_codes[i] == true);
> }
>
> - pthread_cond_destroy(&cond);
> - pthread_mutex_destroy(&mutex);
> + pthread_barrier_destroy(&barrier);
> }
>
> void
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQIcBAEBAgAGBQJPxqsFAAoJEAIvNt057x8iEjsP/2gL5jqUD8NXf6sk2ReXoyH+
gKlOmH0/j4mMim+hxfnGIe3eg2VcP/0vR6be5tgwCuoOEgz+cUEPhPp2lpqbdFDR
zUuWRyoGzZIjI7o/+F3pIVZSO0s5e3o/6e49TcpBI0ftj7F2CPUiSbYUtc5ZiD91
oT0duIGdcLE1AVOZuAIR1MHPGoQiI0Bjd8PPneMZzK5E0kxLkbTy/Y/eQ7jroztm
Igq/WufrcnG9jICKrJI4doA0jzhChYmSRypryNgJx2qekSLq+hefS5QUJVlcOrvT
gWDqXGmfSlcBLgIXy1B+tTp2nItpRfSHBOL/WNSaXIjVg556edgHmEZePhs4mY3y
LyRj2mDUQkNC/AC1Asx82jDw/WaWcLwZRqVjrDIAC7HtRQWLO9XLRiGCUoYk6tj8
e/Mg03bEEexpGTYhTmpQteTAR5/+ffCpHsmkLfzKEHqoE3Et/1I1VsbKEl29PVOG
RtI2qCdE9dTn6Lr9t+NzU8RRed8hBMqRaAUMJJC2E2OQW/PkfpbPnoZrTQWdNqvh
IFXk9p468Oa3ohoiIuZbLcM7ytKujGZE5yCls98hjJ2AYs0kBPeKs6Ouv0+5QGJW
UYxtIUePZGDhHqSLwEMMAnq4QiOVNxOTBmGmGtqpywvi/Ne6Y3Qt8JXzIYEOntZp
w327zF0jfJNv12Vefcle
=WF9E
-----END PGP SIGNATURE-----
More information about the waffle
mailing list