diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-08-31 19:49:31 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-08-31 19:49:31 +0000 |
commit | 033d54a2d43a92cdb1794a4dfece4d465cf36f6b (patch) | |
tree | 398c6f127057702fb0f9254ee1c76e2cb224fdcf /nptl/tst-sem14.c | |
parent | d22e28b070d3d1572d39a463d711c6f223078552 (diff) | |
download | glibc-033d54a2d43a92cdb1794a4dfece4d465cf36f6b.tar.gz glibc-033d54a2d43a92cdb1794a4dfece4d465cf36f6b.tar.xz glibc-033d54a2d43a92cdb1794a4dfece4d465cf36f6b.zip |
Fix sem_post race (bug 14532).
Diffstat (limited to 'nptl/tst-sem14.c')
-rw-r--r-- | nptl/tst-sem14.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/nptl/tst-sem14.c b/nptl/tst-sem14.c new file mode 100644 index 0000000000..949c03fcc6 --- /dev/null +++ b/nptl/tst-sem14.c @@ -0,0 +1,91 @@ +/* Test for sem_post race: bug 14532. + Copyright (C) 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <semaphore.h> +#include <stdio.h> + +#define NTHREADS 10 +#define NITER 100000 + +sem_t sem; +int c; +volatile int thread_fail; + +static void * +tf (void *arg) +{ + for (int i = 0; i < NITER; i++) + { + if (sem_wait (&sem) != 0) + { + perror ("sem_wait"); + thread_fail = 1; + } + ++c; + if (sem_post (&sem) != 0) + { + perror ("sem_post"); + thread_fail = 1; + } + } + return NULL; +} + +static int +do_test (void) +{ + if (sem_init (&sem, 0, 0) != 0) + { + perror ("sem_init"); + return 1; + } + + pthread_t th[NTHREADS]; + for (int i = 0; i < NTHREADS; i++) + { + if (pthread_create (&th[i], NULL, tf, NULL) != 0) + { + puts ("pthread_create failed"); + return 1; + } + } + + if (sem_post (&sem) != 0) + { + perror ("sem_post"); + return 1; + } + + for (int i = 0; i < NTHREADS; i++) + if (pthread_join (th[i], NULL) != 0) + { + puts ("pthread_join failed"); + return 1; + } + + if (c != NTHREADS * NITER) + { + printf ("c = %d, should be %d\n", c, NTHREADS * NITER); + return 1; + } + return thread_fail; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |