diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-02-09 22:55:12 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-02-10 01:03:54 +0000 |
commit | 8a195ec810f3d4acddcbd6c2d753edf11d105798 (patch) | |
tree | a14d1e66dfde577325bd130f6c97e8ed7b654a2b /sysdeps | |
parent | htl: Make sem_wait/sem_timedwait interruptible (diff) | |
download | glibc-8a195ec810f3d4acddcbd6c2d753edf11d105798.tar.gz glibc-8a195ec810f3d4acddcbd6c2d753edf11d105798.tar.bz2 glibc-8a195ec810f3d4acddcbd6c2d753edf11d105798.zip |
pthread: Move most sem tests from nptl to sysdeps/pthread
So they can be checked with htl too.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/mach/hurd/i386/Makefile | 9 | ||||
-rw-r--r-- | sysdeps/pthread/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem1.c | 88 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem10.c | 87 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem14.c | 91 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem15.c | 99 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem16.c | 130 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem2.c | 53 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem3.c | 144 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem4.c | 153 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem6.c | 79 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem7.c | 111 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem8.c | 76 | ||||
-rw-r--r-- | sysdeps/pthread/tst-sem9.c | 83 |
14 files changed, 1205 insertions, 0 deletions
diff --git a/sysdeps/mach/hurd/i386/Makefile b/sysdeps/mach/hurd/i386/Makefile index e303945b2a..a5ccab0956 100644 --- a/sysdeps/mach/hurd/i386/Makefile +++ b/sysdeps/mach/hurd/i386/Makefile @@ -111,6 +111,7 @@ test-xfail-tst-cond13 = yes test-xfail-tst-cond23 = yes test-xfail-tst-rwlock4 = yes test-xfail-tst-rwlock12 = yes +test-xfail-tst-sem3 = yes endif # For bug 25522 @@ -119,6 +120,14 @@ test-xfail-tst-cond24 = yes test-xfail-tst-cond25 = yes endif +# For bug 25524 +ifeq ($(subdir),htl) +test-xfail-tst-sem4 = yes +test-xfail-tst-sem7 = yes +test-xfail-tst-sem8 = yes +test-xfail-tst-sem9 = yes +endif + ifeq ($(subdir),elf) # We do use nested functions involving creation of trampolines, notably for # callbacks whose parameters don't permit to get the context parameters. diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index 8143eeb1ad..2f07c0cfe6 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -55,6 +55,8 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ tst-once1 tst-once2 tst-once3 tst-once4 \ tst-rwlock1 tst-rwlock4 tst-rwlock5 tst-rwlock13 tst-rwlock16 \ tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall \ + tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem6 tst-sem7 \ + tst-sem8 tst-sem9 tst-sem10 tst-sem14 tst-sem15 tst-sem16 \ tst-spin1 tst-spin2 tst-spin3 tst-spin4 tests += tst-oncex3 tst-oncex4 diff --git a/sysdeps/pthread/tst-sem1.c b/sysdeps/pthread/tst-sem1.c new file mode 100644 index 0000000000..ba46e77fbd --- /dev/null +++ b/sysdeps/pthread/tst-sem1.c @@ -0,0 +1,88 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <semaphore.h> +#include <stdio.h> +#include <unistd.h> + + +static int +do_test (void) +{ + sem_t s; + + if (sem_init (&s, 0, 1) == -1) + { + puts ("init failed"); + return 1; + } + + if (TEMP_FAILURE_RETRY (sem_wait (&s)) == -1) + { + puts ("1st wait failed"); + return 1; + } + + if (sem_post (&s) == -1) + { + puts ("1st post failed"); + return 1; + } + + if (TEMP_FAILURE_RETRY (sem_trywait (&s)) == -1) + { + puts ("1st trywait failed"); + return 1; + } + + errno = 0; + if (TEMP_FAILURE_RETRY (sem_trywait (&s)) != -1) + { + puts ("2nd trywait succeeded"); + return 1; + } + else if (errno != EAGAIN) + { + puts ("2nd trywait did not set errno to EAGAIN"); + return 1; + } + + if (sem_post (&s) == -1) + { + puts ("2nd post failed"); + return 1; + } + + if (TEMP_FAILURE_RETRY (sem_wait (&s)) == -1) + { + puts ("2nd wait failed"); + return 1; + } + + if (sem_destroy (&s) == -1) + { + puts ("destroy failed"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-sem10.c b/sysdeps/pthread/tst-sem10.c new file mode 100644 index 0000000000..2f1505003e --- /dev/null +++ b/sysdeps/pthread/tst-sem10.c @@ -0,0 +1,87 @@ +/* Copyright (C) 2007-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2007. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthread.h> +#include <semaphore.h> +#include <stdio.h> +#include <time.h> +#include <unistd.h> +#include <sys/time.h> + + +static int +do_test (void) +{ + sem_t s; + if (sem_init (&s, 0, 0) == -1) + { + puts ("sem_init failed"); + return 1; + } + + struct timeval tv; + if (gettimeofday (&tv, NULL) != 0) + { + puts ("gettimeofday failed"); + return 1; + } + + struct timespec ts; + TIMEVAL_TO_TIMESPEC (&tv, &ts); + + /* Set ts to yesterday. */ + ts.tv_sec -= 86400; + + int type_before; + if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_before) != 0) + { + puts ("first pthread_setcanceltype failed"); + return 1; + } + + errno = 0; + if (TEMP_FAILURE_RETRY (sem_timedwait (&s, &ts)) != -1) + { + puts ("sem_timedwait succeeded"); + return 1; + } + if (errno != ETIMEDOUT) + { + printf ("sem_timedwait return errno = %d instead of ETIMEDOUT\n", + errno); + return 1; + } + + int type_after; + if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_after) != 0) + { + puts ("second pthread_setcanceltype failed"); + return 1; + } + if (type_after != PTHREAD_CANCEL_DEFERRED) + { + puts ("sem_timedwait changed cancellation type"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-sem14.c b/sysdeps/pthread/tst-sem14.c new file mode 100644 index 0000000000..a2461a6a90 --- /dev/null +++ b/sysdeps/pthread/tst-sem14.c @@ -0,0 +1,91 @@ +/* Test for sem_post race: bug 14532. + Copyright (C) 2012-2020 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 + <https://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" diff --git a/sysdeps/pthread/tst-sem15.c b/sysdeps/pthread/tst-sem15.c new file mode 100644 index 0000000000..9a9a93eb32 --- /dev/null +++ b/sysdeps/pthread/tst-sem15.c @@ -0,0 +1,99 @@ +/* Test for SEM_VALUE_MAX overflow detection: BZ #18434. + Copyright (C) 2015-2020 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <limits.h> +#include <semaphore.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + +static int +do_test (void) +{ + sem_t s; + + if (sem_init (&s, 0, SEM_VALUE_MAX)) + { + printf ("sem_init: %m\n"); + return 1; + } + + int result = 0; + + int value = 0xdeadbeef; + if (sem_getvalue (&s, &value)) + { + printf ("sem_getvalue: %m\n"); + result = 1; + } + else + { + printf ("sem_getvalue after init: %d\n", value); + if (value != SEM_VALUE_MAX) + { + printf ("\tshould be %d\n", SEM_VALUE_MAX); + result = 1; + } + } + + errno = 0; + if (sem_post(&s) == 0) + { + puts ("sem_post at SEM_VALUE_MAX succeeded!"); + result = 1; + } + else + { + printf ("sem_post at SEM_VALUE_MAX: %m (%d)\n", errno); + if (errno != EOVERFLOW) + { + printf ("\tshould be %s (EOVERFLOW = %d)\n", + strerror (EOVERFLOW), EOVERFLOW); + result = 1; + } + } + + value = 0xbad1d00d; + if (sem_getvalue (&s, &value)) + { + printf ("sem_getvalue: %m\n"); + result = 1; + } + else + { + printf ("sem_getvalue after post: %d\n", value); + if (value != SEM_VALUE_MAX) + { + printf ("\tshould be %d\n", SEM_VALUE_MAX); + result = 1; + } + } + + if (sem_destroy (&s)) + { + printf ("sem_destroy: %m\n"); + result = 1; + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-sem16.c b/sysdeps/pthread/tst-sem16.c new file mode 100644 index 0000000000..315a92581a --- /dev/null +++ b/sysdeps/pthread/tst-sem16.c @@ -0,0 +1,130 @@ +/* Test for sem_open cancellation handling: BZ #15765. + Copyright (C) 2016-2020 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 + <https://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <sys/mman.h> +#include <semaphore.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +static sem_t sem; /* Use to sync with thread start. */ +static const char pipe_name[] = "/glibc-tst-sem16"; + +static void +remove_sem (int status, void *arg) +{ + sem_unlink (arg); +} + +static void * +tf (void *arg) +{ + pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, 0); + + if (sem_wait (&sem) != 0) + { + printf ("error: sem_wait failed: %m"); + exit (1); + } + + if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0) != 0) + { + printf ("error: pthread_setcancelstate failed: %m"); + exit (1); + } + + /* Neither sem_unlink or sem_open should act on thread cancellation. */ + sem_unlink (pipe_name); + on_exit (remove_sem, (void *) pipe_name); + + sem_t *s = sem_open (pipe_name, O_CREAT, 0600, 1); + if (s == SEM_FAILED) + { + int exit_code; + if (errno == ENOSYS || errno == EACCES) + exit_code = 77; + else + exit_code = 1; + exit (exit_code); + } + + if (pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, 0) != 0) + { + printf ("error: pthread_setcancelstate failed: %m"); + exit (1); + } + + if (sem_close (s) != 0) + { + printf ("error: sem_close failed: %m"); + exit (1); + } + + return NULL; +} + +static int +do_test (void) +{ + pthread_t td; + + if (sem_init (&sem, 0, 0)) + { + printf ("error: sem_init failed: %m\n"); + exit (1); + } + + if (pthread_create (&td, NULL, tf, NULL) != 0) + { + printf ("error: pthread_create failed: %m\n"); + exit (1); + } + + if (pthread_cancel (td) != 0) + { + printf ("error: pthread_cancel failed: %m\n"); + exit (1); + } + + if (sem_post (&sem) != 0) + { + printf ("error: sem_post failed: %m\n"); + exit (1); + } + + void *r; + if (pthread_join (td, &r) != 0) + { + printf ("error: pthread_join failed: %m\n"); + exit (1); + } + + if (r == PTHREAD_CANCELED) + { + puts ("error: pthread_join returned PTHREAD_CANCELED"); + exit (1); + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> diff --git a/sysdeps/pthread/tst-sem2.c b/sysdeps/pthread/tst-sem2.c new file mode 100644 index 0000000000..659c1c81f0 --- /dev/null +++ b/sysdeps/pthread/tst-sem2.c @@ -0,0 +1,53 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthread.h> +#include <semaphore.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> + +static int do_test (void); + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static int +do_test (void) +{ + sem_t s; + + if (sem_init (&s, 0, 0) == -1) + { + puts ("init failed"); + return 1; + } + + delayed_exit (1); + + if (TEMP_FAILURE_RETRY (sem_wait (&s)) == -1) + { + puts ("wait failed"); + return 1; + } + + /* We should never get here. */ + puts ("wait succeeded"); + return 1; +} diff --git a/sysdeps/pthread/tst-sem3.c b/sysdeps/pthread/tst-sem3.c new file mode 100644 index 0000000000..6568840112 --- /dev/null +++ b/sysdeps/pthread/tst-sem3.c @@ -0,0 +1,144 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <semaphore.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/wait.h> + + +int +do_test (void) +{ + size_t ps = sysconf (_SC_PAGESIZE); + char tmpfname[] = "/tmp/tst-sem3.XXXXXX"; + char data[ps]; + void *mem; + int fd; + sem_t *s; + pid_t pid; + char *p; + + fd = mkstemp (tmpfname); + if (fd == -1) + { + printf ("cannot open temporary file: %m\n"); + return 1; + } + + /* Make sure it is always removed. */ + unlink (tmpfname); + + /* Create one page of data. */ + memset (data, '\0', ps); + + /* Write the data to the file. */ + if (write (fd, data, ps) != (ssize_t) ps) + { + puts ("short write"); + return 1; + } + + mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (mem == MAP_FAILED) + { + printf ("mmap failed: %m\n"); + return 1; + } + + s = (sem_t *) (((uintptr_t) mem + __alignof (sem_t)) + & ~(__alignof (sem_t) - 1)); + p = (char *) (s + 1); + + if (sem_init (s, 1, 1) == -1) + { + puts ("init failed"); + return 1; + } + + if (TEMP_FAILURE_RETRY (sem_wait (s)) == -1) + { + puts ("1st wait failed"); + return 1; + } + + errno = 0; + if (TEMP_FAILURE_RETRY (sem_trywait (s)) != -1) + { + puts ("trywait succeeded"); + return 1; + } + else if (errno != EAGAIN) + { + puts ("trywait didn't return EAGAIN"); + return 1; + } + + *p = 0; + + puts ("going to fork now"); + pid = fork (); + if (pid == -1) + { + puts ("fork failed"); + return 1; + } + else if (pid == 0) + { + /* Play some lock ping-pong. It's our turn to unlock first. */ + if ((*p)++ != 0) + { + puts ("child: *p != 0"); + return 1; + } + + if (sem_post (s) == -1) + { + puts ("child: 1st post failed"); + return 1; + } + + puts ("child done"); + } + else + { + if (TEMP_FAILURE_RETRY (sem_wait (s)) == -1) + { + printf ("parent: 2nd wait failed: %m\n"); + return 1; + } + + if (*p != 1) + { + puts ("*p != 1"); + return 1; + } + + puts ("parent done"); + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-sem4.c b/sysdeps/pthread/tst-sem4.c new file mode 100644 index 0000000000..7286627643 --- /dev/null +++ b/sysdeps/pthread/tst-sem4.c @@ -0,0 +1,153 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <semaphore.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static void +remove_sem (int status, void *arg) +{ + sem_unlink (arg); +} + + +int +do_test (void) +{ + sem_t *s; + sem_t *s2; + pid_t pid; + int val; + + /* Start with a clean slate and register a clean-up action. No need to + act if sem_unlink fails because we will catch the same problem during the + sem_open below. */ + sem_unlink ("/glibc-tst-sem4"); + on_exit (remove_sem, (void *) "/glibc-tst-sem4"); + + s = sem_open ("/glibc-tst-sem4", O_CREAT, 0600, 1); + if (s == SEM_FAILED) + { + if (errno == ENOSYS) + { + puts ("sem_open not supported. Oh well."); + return 0; + } + + /* Maybe the shm filesystem has strict permissions. */ + if (errno == EACCES) + { + puts ("sem_open not allowed. Oh well."); + return 0; + } + + printf ("sem_open: %m\n"); + return 1; + } + + /* We have the semaphore object. Now try again with O_EXCL, this + should fail. */ + s2 = sem_open ("/glibc-tst-sem4", O_CREAT | O_EXCL, 0600, 1); + if (s2 != SEM_FAILED) + { + puts ("2nd sem_open didn't fail"); + return 1; + } + if (errno != EEXIST) + { + puts ("2nd sem_open returned wrong error"); + return 1; + } + + /* Check the value. */ + if (sem_getvalue (s, &val) == -1) + { + puts ("getvalue failed"); + return 1; + } + if (val != 1) + { + printf ("initial value wrong: got %d, expected 1\n", val); + return 1; + } + + if (TEMP_FAILURE_RETRY (sem_wait (s)) == -1) + { + puts ("1st sem_wait failed"); + return 1; + } + + pid = fork (); + if (pid == -1) + { + printf ("fork failed: %m\n"); + return 1; + } + + if (pid == 0) + { + /* Child. */ + + /* Check the value. */ + if (sem_getvalue (s, &val) == -1) + { + puts ("child: getvalue failed"); + return 1; + } + if (val != 0) + { + printf ("child: value wrong: got %d, expect 0\n", val); + return 1; + } + + if (sem_post (s) == -1) + { + puts ("child: post failed"); + return 1; + } + } + else + { + if (TEMP_FAILURE_RETRY (sem_wait (s)) == -1) + { + puts ("2nd sem_wait failed"); + return 1; + } + + if (sem_getvalue (s, &val) == -1) + { + puts ("parent: 2nd getvalue failed"); + return 1; + } + if (val != 0) + { + printf ("parent: value wrong: got %d, expected 0\n", val); + return 1; + } + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-sem6.c b/sysdeps/pthread/tst-sem6.c new file mode 100644 index 0000000000..7f74437b06 --- /dev/null +++ b/sysdeps/pthread/tst-sem6.c @@ -0,0 +1,79 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <semaphore.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> + + +static void +handler (int sig) +{ + struct sigaction sa; + + sa.sa_handler = SIG_DFL; + sa.sa_flags = 0; + sigemptyset (&sa.sa_mask); + + sigaction (SIGALRM, &sa, NULL); + + /* Rearm the timer. */ + alarm (1); +} + + +static int +do_test (void) +{ + sem_t s; + struct sigaction sa; + + sa.sa_handler = handler; + sa.sa_flags = 0; + sigemptyset (&sa.sa_mask); + + sigaction (SIGALRM, &sa, NULL); + + if (sem_init (&s, 0, 0) == -1) + { + puts ("init failed"); + return 1; + } + + /* Set an alarm for 1 second. The wrapper will expect this. */ + alarm (1); + + int res = sem_wait (&s); + if (res == 0) + { + puts ("wait succeeded"); + return 1; + } + if (res != -1 || errno != EINTR) + { + puts ("wait didn't fail with EINTR"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-sem7.c b/sysdeps/pthread/tst-sem7.c new file mode 100644 index 0000000000..80f566f787 --- /dev/null +++ b/sysdeps/pthread/tst-sem7.c @@ -0,0 +1,111 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <semaphore.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static void +remove_sem (int status, void *arg) +{ + sem_unlink (arg); +} + + +static int +do_test (void) +{ + sem_t *s; + sem_t *s2; + sem_t *s3; + + s = sem_open ("/glibc-tst-sem7", O_CREAT, 0600, 1); + if (s == SEM_FAILED) + { + if (errno == ENOSYS) + { + puts ("sem_open not supported. Oh well."); + return 0; + } + + /* Maybe the shm filesystem has strict permissions. */ + if (errno == EACCES) + { + puts ("sem_open not allowed. Oh well."); + return 0; + } + + printf ("sem_open: %m\n"); + return 1; + } + + on_exit (remove_sem, (void *) "/glibc-tst-sem7"); + + /* We have the semaphore object. Now try again. We should get the + same address. */ + s2 = sem_open ("/glibc-tst-sem7", O_CREAT, 0600, 1); + if (s2 == SEM_FAILED) + { + puts ("2nd sem_open failed"); + return 1; + } + if (s != s2) + { + puts ("2nd sem_open didn't return the same address"); + return 1; + } + + /* And again, this time without O_CREAT. */ + s3 = sem_open ("/glibc-tst-sem7", 0); + if (s3 == SEM_FAILED) + { + puts ("3rd sem_open failed"); + return 1; + } + if (s != s3) + { + puts ("3rd sem_open didn't return the same address"); + return 1; + } + + /* Now close the handle. Three times. */ + if (sem_close (s2) != 0) + { + puts ("1st sem_close failed"); + return 1; + } + if (sem_close (s) != 0) + { + puts ("2nd sem_close failed"); + return 1; + } + if (sem_close (s3) != 0) + { + puts ("3rd sem_close failed"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-sem8.c b/sysdeps/pthread/tst-sem8.c new file mode 100644 index 0000000000..ebe1ac6fa3 --- /dev/null +++ b/sysdeps/pthread/tst-sem8.c @@ -0,0 +1,76 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <semaphore.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static void +remove_sem (int status, void *arg) +{ + sem_unlink (arg); +} + + +static int +do_test (void) +{ + sem_t *s; + int i; + + on_exit (remove_sem, (void *) "/glibc-tst-sem8"); + + for (i = 0; i < 3; ++i) + { + s = sem_open ("/glibc-tst-sem8", O_CREAT, 0600, 1); + if (s == SEM_FAILED) + { + if (errno == ENOSYS) + { + puts ("sem_open not supported. Oh well."); + return 0; + } + + /* Maybe the shm filesystem has strict permissions. */ + if (errno == EACCES) + { + puts ("sem_open not allowed. Oh well."); + return 0; + } + + printf ("sem_open: %m\n"); + return 1; + } + + /* Now close the handle. */ + if (sem_close (s) != 0) + { + puts ("sem_close failed"); + return 1; + } + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-sem9.c b/sysdeps/pthread/tst-sem9.c new file mode 100644 index 0000000000..d5a4d8b3b6 --- /dev/null +++ b/sysdeps/pthread/tst-sem9.c @@ -0,0 +1,83 @@ +/* Copyright (C) 2003-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <semaphore.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static void +remove_sem (int status, void *arg) +{ + sem_unlink (arg); +} + + +static int +do_test (void) +{ + sem_t *s; + int i; + + on_exit (remove_sem, (void *) "/glibc-tst-sem9"); + + for (i = 0; i < 3; ++i) + { + s = sem_open ("/glibc-tst-sem9", O_CREAT, 0600, 1); + if (s == SEM_FAILED) + { + if (errno == ENOSYS) + { + puts ("sem_open not supported. Oh well."); + return 0; + } + + /* Maybe the shm filesystem has strict permissions. */ + if (errno == EACCES) + { + puts ("sem_open not allowed. Oh well."); + return 0; + } + + printf ("sem_open: %m\n"); + return 1; + } + + /* Now close the handle. */ + if (sem_close (s) != 0) + { + puts ("sem_close failed"); + return 1; + } + + /* And remove it. */ + if (sem_unlink ("/glibc-tst-sem9") != 0) + { + puts ("sem_unlink failed"); + return 1; + } + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |