diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-06-19 14:11:58 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-06-23 15:28:45 -0300 |
commit | 76d0104cedc5395e6742c0d867260963765d707b (patch) | |
tree | 39f890acbdbb86f283f2a2ea9c755e62b37795ce /sysdeps/pthread/tst-cancel28.c | |
parent | 99f9ae4ed0ba9f2c84520b78fd0eeed96a7ed40e (diff) | |
download | glibc-76d0104cedc5395e6742c0d867260963765d707b.tar.gz glibc-76d0104cedc5395e6742c0d867260963765d707b.tar.xz glibc-76d0104cedc5395e6742c0d867260963765d707b.zip |
linux: Do not spawn a new thread for SIGEV_THREAD (BZ 30558) azanella/bz30558-posix_timer
Diffstat (limited to 'sysdeps/pthread/tst-cancel28.c')
-rw-r--r-- | sysdeps/pthread/tst-cancel28.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/sysdeps/pthread/tst-cancel28.c b/sysdeps/pthread/tst-cancel28.c index ae55f38210..2eb78acede 100644 --- a/sysdeps/pthread/tst-cancel28.c +++ b/sysdeps/pthread/tst-cancel28.c @@ -28,48 +28,64 @@ #include <support/xthread.h> static pthread_barrier_t barrier; -static pthread_t timer_thread; + +#define VALUE1_INITIAL 0 +static __thread unsigned int value1 = VALUE1_INITIAL; +#define VALUE2_INITIAL 0xdeadbeef +static __thread unsigned int value2 = VALUE2_INITIAL; + +static int cl_called = 0; static void cl (void *arg) { - xpthread_barrier_wait (&barrier); + cl_called++; + xpthread_barrier_wait (&barrier); /* 1 */ } static void thread_handler (union sigval sv) { - timer_thread = pthread_self (); + /* Check if thread state is correctly reset after a pthread_exit. */ + TEST_COMPARE (value1, VALUE1_INITIAL); + TEST_COMPARE (value2, VALUE2_INITIAL); + + value1 = VALUE2_INITIAL; + value2 = VALUE1_INITIAL; - xpthread_barrier_wait (&barrier); + xpthread_barrier_wait (&barrier); /* 0 */ pthread_cleanup_push (cl, NULL); - while (1) - clock_nanosleep (CLOCK_REALTIME, 0, &(struct timespec) { 1, 0 }, NULL); + pthread_exit (NULL); pthread_cleanup_pop (0); } static int do_test (void) { - struct sigevent sev = { 0 }; - sev.sigev_notify = SIGEV_THREAD; - sev.sigev_notify_function = &thread_handler; + struct sigevent sev = { + .sigev_notify = SIGEV_THREAD, + .sigev_notify_function = &thread_handler, + }; timer_t timerid; TEST_COMPARE (timer_create (CLOCK_REALTIME, &sev, &timerid), 0); xpthread_barrier_init (&barrier, NULL, 2); - struct itimerspec trigger = { 0 }; - trigger.it_value.tv_nsec = 1000000; + struct itimerspec trigger = { { 0, 1000000 }, { 0, 1000000 } }; TEST_COMPARE (timer_settime (timerid, 0, &trigger, NULL), 0); - xpthread_barrier_wait (&barrier); + enum { TIMERS_TO_CHECK = 4 }; + for (int i = 0; i < TIMERS_TO_CHECK; i++) + { + /* Check the thread local values. */ + xpthread_barrier_wait (&barrier); /* 0 */ - xpthread_cancel (timer_thread); + xpthread_barrier_wait (&barrier); /* 1 */ + } - xpthread_barrier_wait (&barrier); + TEST_COMPARE (cl_called, TIMERS_TO_CHECK); return 0; } |