Message ID | 4e263237-17f1-0fd3-97bf-537ad937646b@redhat.com |
---|---|
State | New |
Headers | show |
Series | Add threaded test of sem_trywait | expand |
Ping. This patch <https://sourceware.org/pipermail/libc-alpha/2024-November/161321.html> is pending review. (Assume the new test is renamed to tst-sem19.)
Ping^2. This patch <https://sourceware.org/pipermail/libc-alpha/2024-November/161321.html> is still pending review. (Assume the new test is renamed to tst-sem19.)
On 11/7/24 8:49 PM, Joseph Myers wrote: > All the existing glibc tests of sem_trywait are single-threaded. Add > one that calls sem_trywait and sem_post in separate threads. > > Tested for x86_64. Tests should have a description of intent. Looking forward to a v2. > diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile > index 4c1dc04b20..1a9f2559d9 100644 > --- a/sysdeps/pthread/Makefile > +++ b/sysdeps/pthread/Makefile > @@ -256,6 +256,7 @@ tests += \ > tst-sem14 \ > tst-sem15 \ > tst-sem16 \ > + tst-sem18 \ OK. New test. > tst-setuid3 \ > tst-signal1 \ > tst-signal2 \ > diff --git a/sysdeps/pthread/tst-sem18.c b/sysdeps/pthread/tst-sem18.c > new file mode 100644 > index 0000000000..ade311473e > --- /dev/null > +++ b/sysdeps/pthread/tst-sem18.c > @@ -0,0 +1,68 @@ > +/* Test sem_trywait with threads. OK. One line description. > + Copyright (C) 2024 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 <pthread.h> > +#include <semaphore.h> > +#include <support/check.h> > +#include <support/xthread.h> > + This needs an explanation of the intent of the test. Suggest: /* The test uses two threads, the main thread and a newly created thread to test the operation of sem_trywait in a threaded scenario. The intent is to test sem_trywait when it would return EAGAIN, and then again after the critical section in the new thread has posted to the semaphore and the main thread succeeds in calling sem_trywait. It is possible this test fails with a timeout if the second thread takes longer than the test timeout to acquire the lock, and post. */ > +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; > +static sem_t sem; > + > +static void * > +tf (void *arg) > +{ > + xpthread_mutex_lock (&lock); > + sem_post (&sem); > + xpthread_mutex_unlock (&lock); > + return NULL; > +} > + > +static int > +do_test (void) > +{ > + int ret; > + > + ret = sem_init (&sem, 0, 0); > + TEST_VERIFY_EXIT (ret == 0); > + xpthread_mutex_lock (&lock); > + pthread_t th = xpthread_create (NULL, tf, NULL); > + errno = 0; > + /* The other thread is waiting on the lock before it calls sem_post, > + so sem_trywait should fail. */ > + ret = sem_trywait (&sem); OK. Correct. > + TEST_COMPARE (ret, -1); > + TEST_COMPARE (errno, EAGAIN); > + xpthread_mutex_unlock (&lock); OK. > + /* The other thread now takes the lock, calls sem_post and releases > + the lock. */ > + for (;;) > + { > + errno = 0; > + ret = sem_trywait (&sem); > + if (ret == 0) > + break; > + TEST_COMPARE (errno, EAGAIN); OK. This must loop until we succeed or timeout. This *might* timeout if the thread takes longer than the test timeout to complete, but that's not a problem we can easily solve and it should work. > + } > + xpthread_join (th); > + > + return 0; > +} > + > +#include <support/test-driver.c> >
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index 4c1dc04b20..1a9f2559d9 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -256,6 +256,7 @@ tests += \ tst-sem14 \ tst-sem15 \ tst-sem16 \ + tst-sem18 \ tst-setuid3 \ tst-signal1 \ tst-signal2 \ diff --git a/sysdeps/pthread/tst-sem18.c b/sysdeps/pthread/tst-sem18.c new file mode 100644 index 0000000000..ade311473e --- /dev/null +++ b/sysdeps/pthread/tst-sem18.c @@ -0,0 +1,68 @@ +/* Test sem_trywait with threads. + Copyright (C) 2024 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 <pthread.h> +#include <semaphore.h> +#include <support/check.h> +#include <support/xthread.h> + +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +static sem_t sem; + +static void * +tf (void *arg) +{ + xpthread_mutex_lock (&lock); + sem_post (&sem); + xpthread_mutex_unlock (&lock); + return NULL; +} + +static int +do_test (void) +{ + int ret; + + ret = sem_init (&sem, 0, 0); + TEST_VERIFY_EXIT (ret == 0); + xpthread_mutex_lock (&lock); + pthread_t th = xpthread_create (NULL, tf, NULL); + errno = 0; + /* The other thread is waiting on the lock before it calls sem_post, + so sem_trywait should fail. */ + ret = sem_trywait (&sem); + TEST_COMPARE (ret, -1); + TEST_COMPARE (errno, EAGAIN); + xpthread_mutex_unlock (&lock); + /* The other thread now takes the lock, calls sem_post and releases + the lock. */ + for (;;) + { + errno = 0; + ret = sem_trywait (&sem); + if (ret == 0) + break; + TEST_COMPARE (errno, EAGAIN); + } + xpthread_join (th); + + return 0; +} + +#include <support/test-driver.c>