From 71d52ac4d65435791d8fa9f52abab7107ef7f7e8 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 9 Feb 2020 17:00:39 +0000 Subject: pthread: Move spin tests from nptl to sysdeps/pthread So they can be checked with htl too. --- nptl/Makefile | 1 - nptl/tst-spin1.c | 56 ---------------- nptl/tst-spin2.c | 158 -------------------------------------------- nptl/tst-spin3.c | 53 --------------- nptl/tst-spin4.c | 108 ------------------------------ sysdeps/pthread/Makefile | 1 + sysdeps/pthread/tst-spin1.c | 56 ++++++++++++++++ sysdeps/pthread/tst-spin2.c | 158 ++++++++++++++++++++++++++++++++++++++++++++ sysdeps/pthread/tst-spin3.c | 53 +++++++++++++++ sysdeps/pthread/tst-spin4.c | 108 ++++++++++++++++++++++++++++++ 10 files changed, 376 insertions(+), 376 deletions(-) delete mode 100644 nptl/tst-spin1.c delete mode 100644 nptl/tst-spin2.c delete mode 100644 nptl/tst-spin3.c delete mode 100644 nptl/tst-spin4.c create mode 100644 sysdeps/pthread/tst-spin1.c create mode 100644 sysdeps/pthread/tst-spin2.c create mode 100644 sysdeps/pthread/tst-spin3.c create mode 100644 sysdeps/pthread/tst-spin4.c diff --git a/nptl/Makefile b/nptl/Makefile index 812d01a..baa6c667 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -240,7 +240,6 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \ tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ tst-mutexpi9 \ - tst-spin1 tst-spin2 tst-spin3 tst-spin4 \ tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \ tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \ diff --git a/nptl/tst-spin1.c b/nptl/tst-spin1.c deleted file mode 100644 index 3480f40..0000000 --- a/nptl/tst-spin1.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include - - -static int -do_test (void) -{ - pthread_spinlock_t s; - - if (pthread_spin_init (&s, PTHREAD_PROCESS_PRIVATE) != 0) - { - puts ("spin_init failed"); - return 1; - } - - if (pthread_spin_lock (&s) != 0) - { - puts ("spin_lock failed"); - return 1; - } - - if (pthread_spin_unlock (&s) != 0) - { - puts ("spin_unlock failed"); - return 1; - } - - if (pthread_spin_destroy (&s) != 0) - { - puts ("spin_destroy failed"); - return 1; - } - - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-spin2.c b/nptl/tst-spin2.c deleted file mode 100644 index 135228a..0000000 --- a/nptl/tst-spin2.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int -do_test (void) -{ - size_t ps = sysconf (_SC_PAGESIZE); - char tmpfname[] = "/tmp/tst-spin2.XXXXXX"; - char data[ps]; - void *mem; - int fd; - pthread_spinlock_t *s; - pid_t pid; - char *p; - int err; - - 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 = (pthread_spinlock_t *) (((uintptr_t) mem - + __alignof (pthread_spinlock_t)) - & ~(__alignof (pthread_spinlock_t) - 1)); - p = (char *) (s + 1); - - if (pthread_spin_init (s, PTHREAD_PROCESS_SHARED) != 0) - { - puts ("spin_init failed"); - return 1; - } - - if (pthread_spin_lock (s) != 0) - { - puts ("spin_lock failed"); - return 1; - } - - err = pthread_spin_trylock (s); - if (err == 0) - { - puts ("1st spin_trylock succeeded"); - return 1; - } - else if (err != EBUSY) - { - puts ("1st spin_trylock didn't return EBUSY"); - return 1; - } - - err = pthread_spin_unlock (s); - if (err != 0) - { - puts ("parent: spin_unlock failed"); - return 1; - } - - err = pthread_spin_trylock (s); - if (err != 0) - { - puts ("2nd spin_trylock failed"); - 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 (pthread_spin_unlock (s) != 0) - { - puts ("child: 1st spin_unlock failed"); - return 1; - } - - puts ("child done"); - } - else - { - if (pthread_spin_lock (s) != 0) - { - puts ("parent: 2nd spin_lock failed"); - return 1; - } - - puts ("waiting for child"); - - waitpid (pid, NULL, 0); - - puts ("parent done"); - } - - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/nptl/tst-spin3.c b/nptl/tst-spin3.c deleted file mode 100644 index d64dab4..0000000 --- a/nptl/tst-spin3.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include - -static int do_test (void); - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" - -static int -do_test (void) -{ - pthread_spinlock_t s; - - if (pthread_spin_init (&s, PTHREAD_PROCESS_PRIVATE) != 0) - { - puts ("spin_init failed"); - return 1; - } - - if (pthread_spin_lock (&s) != 0) - { - puts ("1st spin_lock failed"); - return 1; - } - - delayed_exit (1); - - /* This call should never return. */ - xpthread_spin_lock (&s); - - puts ("2nd spin_lock returned"); - return 1; -} diff --git a/nptl/tst-spin4.c b/nptl/tst-spin4.c deleted file mode 100644 index 99fe7aa..0000000 --- a/nptl/tst-spin4.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include - -static int count = 0; - -static void * -thread_add_one (void *arg) -{ - int tmp; - pthread_spinlock_t *lock = (pthread_spinlock_t *) arg; - - /* When do_test holds the lock for 1 sec, the two thread will be - in contention for the lock. */ - if (pthread_spin_lock (lock) != 0) - { - puts ("thread_add_one(): spin_lock failed"); - pthread_exit ((void *) 1l); - } - - /* sleep 1s before modifying count */ - tmp = count; - sleep (1); - count = tmp + 1; - - if (pthread_spin_unlock (lock) != 0) - { - puts ("thread_add_one(): spin_unlock failed"); - pthread_exit ((void *) 1l); - } - - return NULL; -} - -static int -do_test (void) -{ - pthread_t thr1, thr2; - pthread_spinlock_t lock; - int tmp; - - if (pthread_spin_init (&lock, PTHREAD_PROCESS_PRIVATE) != 0) - { - puts ("spin_init failed"); - return 1; - } - - if (pthread_spin_lock (&lock) != 0) - { - puts ("1st spin_lock failed"); - return 1; - } - - if (pthread_create (&thr1, NULL, thread_add_one, (void *) &lock) != 0) - { - puts ("1st pthread_create failed"); - return 1; - } - - if (pthread_create (&thr2, NULL, thread_add_one, (void *) &lock) != 0) - { - puts ("2nd pthread_create failed"); - return 1; - } - - /* sleep 1s before modifying count */ - tmp = count; - sleep (1); - count = tmp + 1; - - if (pthread_spin_unlock (&lock) != 0) - { - puts ("1st spin_unlock failed"); - return 1; - } - - void *status; - if (pthread_join (thr1, &status) != 0) - { - puts ("1st pthread_join failed"); - return 1; - } - if (status != NULL) - { - puts ("failure in the 1st thread"); - return 1; - } - if (pthread_join (thr2, &status) != 0) - { - puts ("2nd pthread_join failed"); - return 1; - } - if (status != NULL) - { - puts ("failure in the 2nd thread"); - return 1; - } - - if (count != 3) - { - printf ("count is %d, should be 3\n", count); - return 1; - } - return 0; -} - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index db4d573..6b66031 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -44,5 +44,6 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \ tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ tst-basic7 \ + tst-spin1 tst-spin2 tst-spin3 tst-spin4 \ endif diff --git a/sysdeps/pthread/tst-spin1.c b/sysdeps/pthread/tst-spin1.c new file mode 100644 index 0000000..3480f40 --- /dev/null +++ b/sysdeps/pthread/tst-spin1.c @@ -0,0 +1,56 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 + . */ + +#include +#include + + +static int +do_test (void) +{ + pthread_spinlock_t s; + + if (pthread_spin_init (&s, PTHREAD_PROCESS_PRIVATE) != 0) + { + puts ("spin_init failed"); + return 1; + } + + if (pthread_spin_lock (&s) != 0) + { + puts ("spin_lock failed"); + return 1; + } + + if (pthread_spin_unlock (&s) != 0) + { + puts ("spin_unlock failed"); + return 1; + } + + if (pthread_spin_destroy (&s) != 0) + { + puts ("spin_destroy failed"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-spin2.c b/sysdeps/pthread/tst-spin2.c new file mode 100644 index 0000000..135228a --- /dev/null +++ b/sysdeps/pthread/tst-spin2.c @@ -0,0 +1,158 @@ +/* Copyright (C) 2002-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int +do_test (void) +{ + size_t ps = sysconf (_SC_PAGESIZE); + char tmpfname[] = "/tmp/tst-spin2.XXXXXX"; + char data[ps]; + void *mem; + int fd; + pthread_spinlock_t *s; + pid_t pid; + char *p; + int err; + + 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 = (pthread_spinlock_t *) (((uintptr_t) mem + + __alignof (pthread_spinlock_t)) + & ~(__alignof (pthread_spinlock_t) - 1)); + p = (char *) (s + 1); + + if (pthread_spin_init (s, PTHREAD_PROCESS_SHARED) != 0) + { + puts ("spin_init failed"); + return 1; + } + + if (pthread_spin_lock (s) != 0) + { + puts ("spin_lock failed"); + return 1; + } + + err = pthread_spin_trylock (s); + if (err == 0) + { + puts ("1st spin_trylock succeeded"); + return 1; + } + else if (err != EBUSY) + { + puts ("1st spin_trylock didn't return EBUSY"); + return 1; + } + + err = pthread_spin_unlock (s); + if (err != 0) + { + puts ("parent: spin_unlock failed"); + return 1; + } + + err = pthread_spin_trylock (s); + if (err != 0) + { + puts ("2nd spin_trylock failed"); + 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 (pthread_spin_unlock (s) != 0) + { + puts ("child: 1st spin_unlock failed"); + return 1; + } + + puts ("child done"); + } + else + { + if (pthread_spin_lock (s) != 0) + { + puts ("parent: 2nd spin_lock failed"); + return 1; + } + + puts ("waiting for child"); + + waitpid (pid, NULL, 0); + + puts ("parent done"); + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/pthread/tst-spin3.c b/sysdeps/pthread/tst-spin3.c new file mode 100644 index 0000000..d64dab4 --- /dev/null +++ b/sysdeps/pthread/tst-spin3.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 , 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 + . */ + +#include +#include +#include +#include + +static int do_test (void); + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static int +do_test (void) +{ + pthread_spinlock_t s; + + if (pthread_spin_init (&s, PTHREAD_PROCESS_PRIVATE) != 0) + { + puts ("spin_init failed"); + return 1; + } + + if (pthread_spin_lock (&s) != 0) + { + puts ("1st spin_lock failed"); + return 1; + } + + delayed_exit (1); + + /* This call should never return. */ + xpthread_spin_lock (&s); + + puts ("2nd spin_lock returned"); + return 1; +} diff --git a/sysdeps/pthread/tst-spin4.c b/sysdeps/pthread/tst-spin4.c new file mode 100644 index 0000000..99fe7aa --- /dev/null +++ b/sysdeps/pthread/tst-spin4.c @@ -0,0 +1,108 @@ +#include +#include +#include + +static int count = 0; + +static void * +thread_add_one (void *arg) +{ + int tmp; + pthread_spinlock_t *lock = (pthread_spinlock_t *) arg; + + /* When do_test holds the lock for 1 sec, the two thread will be + in contention for the lock. */ + if (pthread_spin_lock (lock) != 0) + { + puts ("thread_add_one(): spin_lock failed"); + pthread_exit ((void *) 1l); + } + + /* sleep 1s before modifying count */ + tmp = count; + sleep (1); + count = tmp + 1; + + if (pthread_spin_unlock (lock) != 0) + { + puts ("thread_add_one(): spin_unlock failed"); + pthread_exit ((void *) 1l); + } + + return NULL; +} + +static int +do_test (void) +{ + pthread_t thr1, thr2; + pthread_spinlock_t lock; + int tmp; + + if (pthread_spin_init (&lock, PTHREAD_PROCESS_PRIVATE) != 0) + { + puts ("spin_init failed"); + return 1; + } + + if (pthread_spin_lock (&lock) != 0) + { + puts ("1st spin_lock failed"); + return 1; + } + + if (pthread_create (&thr1, NULL, thread_add_one, (void *) &lock) != 0) + { + puts ("1st pthread_create failed"); + return 1; + } + + if (pthread_create (&thr2, NULL, thread_add_one, (void *) &lock) != 0) + { + puts ("2nd pthread_create failed"); + return 1; + } + + /* sleep 1s before modifying count */ + tmp = count; + sleep (1); + count = tmp + 1; + + if (pthread_spin_unlock (&lock) != 0) + { + puts ("1st spin_unlock failed"); + return 1; + } + + void *status; + if (pthread_join (thr1, &status) != 0) + { + puts ("1st pthread_join failed"); + return 1; + } + if (status != NULL) + { + puts ("failure in the 1st thread"); + return 1; + } + if (pthread_join (thr2, &status) != 0) + { + puts ("2nd pthread_join failed"); + return 1; + } + if (status != NULL) + { + puts ("failure in the 2nd thread"); + return 1; + } + + if (count != 3) + { + printf ("count is %d, should be 3\n", count); + return 1; + } + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" -- cgit v1.1