public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: Florian Weimer <fweimer@redhat.com>, libc-alpha@sourceware.org
Subject: Re: [PATCH 28/34] Linux: Move timer helper routines from librt to libc
Date: Thu, 24 Jun 2021 11:41:48 -0300	[thread overview]
Message-ID: <685c2e51-f9d9-d93d-9fd5-1906a8efc490@linaro.org> (raw)
In-Reply-To: <a915bc06ac9890175be6bab339931dc74f3c250c.1623956058.git.fweimer@redhat.com>



On 17/06/2021 15:59, Florian Weimer via Libc-alpha wrote:
> This adds several temporary GLIBC_PRIVATE exports.  The symbol names
> are changed so that they all start with __timer_.
> 
> It is now possible to invoke the fork handler directly, so
> pthread_atfork is no longer necessary.  The associated error cannot
> happen anymore, and cancellation handling can be removed from
> the helper thread routine.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>


> ---
>  sysdeps/nptl/Makefile                         |  2 +-
>  sysdeps/nptl/fork.c                           |  2 +
>  sysdeps/unix/sysv/linux/Versions              |  5 ++
>  sysdeps/unix/sysv/linux/kernel-posix-timers.h | 22 ++++---
>  sysdeps/unix/sysv/linux/timer_create.c        | 14 ++---
>  sysdeps/unix/sysv/linux/timer_delete.c        | 10 ++--
>  sysdeps/unix/sysv/linux/timer_routines.c      | 59 +++++++++----------
>  7 files changed, 64 insertions(+), 50 deletions(-)
> 
> diff --git a/sysdeps/nptl/Makefile b/sysdeps/nptl/Makefile
> index 0707f130eb..27aa41af3c 100644
> --- a/sysdeps/nptl/Makefile
> +++ b/sysdeps/nptl/Makefile
> @@ -17,7 +17,7 @@
>  # <https://www.gnu.org/licenses/>.
>  
>  ifeq ($(subdir),rt)
> -librt-sysdep_routines += timer_routines
> +sysdep_routines += timer_routines
>  
>  tests += tst-mqueue8x
>  CFLAGS-tst-mqueue8x.c += -fexceptions

Ok.

> diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
> index d6a0996b79..930716c403 100644
> --- a/sysdeps/nptl/fork.c
> +++ b/sysdeps/nptl/fork.c
> @@ -37,6 +37,7 @@
>  #include <sys/single_threaded.h>
>  #include <list.h>
>  #include <mqueue.h>
> +#include <kernel-posix-timers.h>
>  
>  static void
>  fresetlockfiles (void)
> @@ -231,6 +232,7 @@ __libc_fork (void)
>  	  _IO_list_resetlock ();
>  
>  	  call_function_static_weak (__mq_notify_fork_subprocess);
> +	  call_function_static_weak (__timer_fork_subprocess);
>  
>  	  call_function_static_weak (__nss_database_fork_subprocess,
>  				     &nss_database_data);

Ok.

> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> index 051ecf9390..47d4357b9f 100644
> --- a/sysdeps/unix/sysv/linux/Versions
> +++ b/sysdeps/unix/sysv/linux/Versions
> @@ -282,6 +282,11 @@ libc {
>      __pread64_nocancel;
>      __close_nocancel;
>      __sigtimedwait;
> +    __timer_active_sigev_thread;
> +    __timer_active_sigev_thread_lock;
> +    __timer_helper_once;
> +    __timer_helper_tid;
> +    __timer_start_helper_thread;
>      # functions used by nscd
>      __netlink_assert_response;
>    }

Ok.

> diff --git a/sysdeps/unix/sysv/linux/kernel-posix-timers.h b/sysdeps/unix/sysv/linux/kernel-posix-timers.h
> index 959a81a4d2..17fc32d48f 100644
> --- a/sysdeps/unix/sysv/linux/kernel-posix-timers.h
> +++ b/sysdeps/unix/sysv/linux/kernel-posix-timers.h
> @@ -26,19 +26,27 @@
>  extern int __no_posix_timers attribute_hidden;
>  
>  /* Callback to start helper thread.  */
> -extern void __start_helper_thread (void) attribute_hidden;
> +extern void __timer_start_helper_thread (void);
> +libc_hidden_proto (__timer_start_helper_thread)
>  
>  /* Control variable for helper thread creation.  */
> -extern pthread_once_t __helper_once attribute_hidden;
> +extern pthread_once_t __timer_helper_once;
> +libc_hidden_proto (__timer_helper_once)
> +
> +/* Called from fork so that the new subprocess re-creates the
> +   notification thread if necessary.  */
> +void __timer_fork_subprocess (void) attribute_hidden;
>  
>  /* TID of the helper thread.  */
> -extern pid_t __helper_tid attribute_hidden;
> +extern pid_t __timer_helper_tid;
> +libc_hidden_proto (__timer_helper_tid)
>  
>  /* List of active SIGEV_THREAD timers.  */
> -extern struct timer *__active_timer_sigev_thread attribute_hidden;
> -/* Lock for the __active_timer_sigev_thread.  */
> -extern pthread_mutex_t __active_timer_sigev_thread_lock attribute_hidden;
> -
> +extern struct timer *__timer_active_sigev_thread;
> +libc_hidden_proto (__timer_active_sigev_thread)
> +/* Lock for __timer_active_sigev_thread.  */
> +extern pthread_mutex_t __timer_active_sigev_thread_lock;
> +libc_hidden_proto (__timer_active_sigev_thread_lock)
>  
>  /* Type of timers in the kernel.  */
>  typedef int kernel_timer_t;

Ok.

> diff --git a/sysdeps/unix/sysv/linux/timer_create.c b/sysdeps/unix/sysv/linux/timer_create.c
> index 1ea0086487..b21b0ca949 100644
> --- a/sysdeps/unix/sysv/linux/timer_create.c
> +++ b/sysdeps/unix/sysv/linux/timer_create.c
> @@ -74,8 +74,8 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
>      else
>        {
>  	/* Create the helper thread.  */
> -	pthread_once (&__helper_once, __start_helper_thread);
> -	if (__helper_tid == 0)
> +	pthread_once (&__timer_helper_once, __timer_start_helper_thread);
> +	if (__timer_helper_tid == 0)
>  	  {
>  	    /* No resources to start the helper thread.  */
>  	    __set_errno (EAGAIN);

Ok.

> @@ -118,7 +118,7 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
>  	  { .sigev_value.sival_ptr = newp,
>  	    .sigev_signo = SIGTIMER,
>  	    .sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID,
> -	    ._sigev_un = { ._pad = { [0] = __helper_tid } } };
> +	    ._sigev_un = { ._pad = { [0] = __timer_helper_tid } } };
>  
>  	/* Create the timer.  */
>  	int res;
> @@ -132,10 +132,10 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
>  	  }
>  
>  	/* Add to the queue of active timers with thread delivery.  */
> -	pthread_mutex_lock (&__active_timer_sigev_thread_lock);
> -	newp->next = __active_timer_sigev_thread;
> -	__active_timer_sigev_thread = newp;
> -	pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
> +	pthread_mutex_lock (&__timer_active_sigev_thread_lock);
> +	newp->next = __timer_active_sigev_thread;
> +	__timer_active_sigev_thread = newp;
> +	pthread_mutex_unlock (&__timer_active_sigev_thread_lock);
>  
>  	*timerid = timer_to_timerid (newp);
>        }

Ok.

> diff --git a/sysdeps/unix/sysv/linux/timer_delete.c b/sysdeps/unix/sysv/linux/timer_delete.c
> index 50aac8fc27..a7a183591e 100644
> --- a/sysdeps/unix/sysv/linux/timer_delete.c
> +++ b/sysdeps/unix/sysv/linux/timer_delete.c
> @@ -42,12 +42,12 @@ timer_delete (timer_t timerid)
>  	  struct timer *kt = timerid_to_timer (timerid);
>  
>  	  /* Remove the timer from the list.  */
> -	  pthread_mutex_lock (&__active_timer_sigev_thread_lock);
> -	  if (__active_timer_sigev_thread == kt)
> -	    __active_timer_sigev_thread = kt->next;
> +	  pthread_mutex_lock (&__timer_active_sigev_thread_lock);
> +	  if (__timer_active_sigev_thread == kt)
> +	    __timer_active_sigev_thread = kt->next;
>  	  else
>  	    {
> -	      struct timer *prevp = __active_timer_sigev_thread;
> +	      struct timer *prevp = __timer_active_sigev_thread;
>  	      while (prevp->next != NULL)
>  		if (prevp->next == kt)
>  		  {

Ok.

> @@ -57,7 +57,7 @@ timer_delete (timer_t timerid)
>  		else
>  		  prevp = prevp->next;
>  	    }
> -	  pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
> +	  pthread_mutex_unlock (&__timer_active_sigev_thread_lock);
>  
>  	  free (kt);
>  	}

Ok.

> diff --git a/sysdeps/unix/sysv/linux/timer_routines.c b/sysdeps/unix/sysv/linux/timer_routines.c
> index 4098da8a5f..8d8c1a1e76 100644
> --- a/sysdeps/unix/sysv/linux/timer_routines.c
> +++ b/sysdeps/unix/sysv/linux/timer_routines.c
> @@ -26,10 +26,13 @@
>  
>  
>  /* List of active SIGEV_THREAD timers.  */
> -struct timer *__active_timer_sigev_thread;
> -/* Lock for the __active_timer_sigev_thread.  */
> -pthread_mutex_t __active_timer_sigev_thread_lock = PTHREAD_MUTEX_INITIALIZER;
> +struct timer *__timer_active_sigev_thread __attribute__ ((nocommon));
> +libc_hidden_data_def (__timer_active_sigev_thread)
>  
> +/* Lock for _timer_active_sigev_thread.  */
> +pthread_mutex_t __timer_active_sigev_thread_lock __attribute__ ((nocommon))
> +  = PTHREAD_MUTEX_INITIALIZER;
> +libc_hidden_data_def (__timer_active_sigev_thread_lock)
>  
>  struct thread_start_data
>  {

Ok.  I think we should either use a macro initializer for global without
an initialization or add a attribute macro on cdef.h for 
__attribute__ ((nocommon).

> @@ -59,7 +62,7 @@ timer_sigev_thread (void *arg)
>  
>  
>  /* Helper function to support starting threads for SIGEV_THREAD.  */
> -static void *
> +static _Noreturn void *
>  timer_helper_thread (void *arg)
>  {
>    /* Endless loop of waiting for signals.  The loop is only ended when

Ok.

> @@ -68,16 +71,16 @@ timer_helper_thread (void *arg)
>      {
>        siginfo_t si;
>  
> -      while (sigwaitinfo (&sigtimer_set, &si) < 0);
> +      while (__sigwaitinfo (&sigtimer_set, &si) < 0);
>        if (si.si_code == SI_TIMER)
>  	{
>  	  struct timer *tk = (struct timer *) si.si_ptr;
>  
>  	  /* Check the timer is still used and will not go away
>  	     while we are reading the values here.  */
> -	  pthread_mutex_lock (&__active_timer_sigev_thread_lock);
> +	  __pthread_mutex_lock (&__timer_active_sigev_thread_lock);
>  
> -	  struct timer *runp = __active_timer_sigev_thread;
> +	  struct timer *runp = __timer_active_sigev_thread;
>  	  while (runp != NULL)
>  	    if (runp == tk)
>  	      break;

Ok.

> @@ -96,45 +99,44 @@ timer_helper_thread (void *arg)
>  		  td->sival = tk->sival;
>  
>  		  pthread_t th;
> -		  pthread_create (&th, &tk->attr, timer_sigev_thread, td);
> +		  __pthread_create (&th, &tk->attr, timer_sigev_thread, td);
>  		}
>  	    }
>  
> -	  pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
> +	  __pthread_mutex_unlock (&__timer_active_sigev_thread_lock);
>  	}
> -      else if (si.si_code == SI_TKILL)
> -	/* The thread is canceled.  */
> -	pthread_exit (NULL);
>      }
>  }
>  
>  
>  /* Control variable for helper thread creation.  */
> -pthread_once_t __helper_once attribute_hidden;
> +pthread_once_t __timer_helper_once __attribute__ ((nocommon))
> +  = PTHREAD_ONCE_INIT;
> +libc_hidden_data_def (__timer_helper_once)
>  
>  
>  /* TID of the helper thread.  */
> -pid_t __helper_tid attribute_hidden;
> +pid_t __timer_helper_tid __attribute__ ((nocommon));
> +libc_hidden_data_def (__timer_helper_tid)
>  
>  
>  /* Reset variables so that after a fork a new helper thread gets started.  */
> -static void
> -reset_helper_control (void)
> +void
> +__timer_fork_subprocess (void)
>  {
> -  __helper_once = PTHREAD_ONCE_INIT;
> -  __helper_tid = 0;
> +  __timer_helper_once = PTHREAD_ONCE_INIT;
> +  __timer_helper_tid = 0;
>  }
>  
>  

Ok.

>  void
> -attribute_hidden
> -__start_helper_thread (void)
> +__timer_start_helper_thread (void)
>  {
>    /* The helper thread needs only very little resources
>       and should go away automatically when canceled.  */
>    pthread_attr_t attr;
> -  (void) pthread_attr_init (&attr);
> -  (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr));
> +  (void) __pthread_attr_init (&attr);
> +  (void) __pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr));
>  
>    /* Block all signals in the helper thread but SIGSETXID.  */
>    sigset_t ss;

No need the extra casts here.

> @@ -143,21 +145,18 @@ __start_helper_thread (void)
>    int res = __pthread_attr_setsigmask_internal (&attr, &ss);
>    if (res != 0)
>      {
> -      pthread_attr_destroy (&attr);
> +      __pthread_attr_destroy (&attr);
>        return;
>      }
>  
>    /* Create the helper thread for this timer.  */
>    pthread_t th;
> -  res = pthread_create (&th, &attr, timer_helper_thread, NULL);
> +  res = __pthread_create (&th, &attr, timer_helper_thread, NULL);
>    if (res == 0)
>      /* We managed to start the helper thread.  */
> -    __helper_tid = ((struct pthread *) th)->tid;
> +    __timer_helper_tid = ((struct pthread *) th)->tid;
>  
>    /* No need for the attribute anymore.  */
> -  (void) pthread_attr_destroy (&attr);
> -
> -  /* We have to make sure that after fork()ing a new helper thread can
> -     be created.  */
> -  pthread_atfork (NULL, NULL, reset_helper_control);
> +  (void) __pthread_attr_destroy (&attr);
>  }
> +libc_hidden_def (__timer_start_helper_thread)
> 

Ok.

  reply	other threads:[~2021-06-24 14:41 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-17 18:56 [PATCH v2 00/34] Move librt into libc Florian Weimer
2021-06-17 18:56 ` [PATCH 01/34] rt: Lexicographically sort Versions file; librt-routines in Makefile Florian Weimer
2021-06-17 18:56 ` [PATCH 02/34] Fix librt-routines-var issues for !PTHREAD_IN_LIBC Florian Weimer
2021-06-17 18:56 ` [PATCH 03/34] rt: Replace generic stub of shm_open with the posix version Florian Weimer
2021-06-17 18:57 ` [PATCH 04/34] rt: Replace generic stub of shm_unlink " Florian Weimer
2021-06-17 18:57 ` [PATCH 05/34] rt: Move shm_open into libc Florian Weimer
2021-06-17 18:57 ` [PATCH 06/34] rt: Move shm_unlink " Florian Weimer
2021-06-17 18:57 ` [PATCH 07/34] rt: Move generic implementation from sysdeps/pthread to rt Florian Weimer
2021-06-21 18:37   ` Adhemerval Zanella
2021-06-17 18:57 ` [PATCH 08/34] nptl: Move pthreadP.h into sysdeps directory Florian Weimer
2021-06-22  0:57   ` Adhemerval Zanella
2021-06-17 18:57 ` [PATCH 09/34] Add hidden prototypes for fsync, fdatasync Florian Weimer
2021-06-22  0:58   ` Adhemerval Zanella
2021-06-17 18:57 ` [PATCH 10/34] Linux: Move aio_init from librt into libc Florian Weimer
2021-06-23 13:22   ` Adhemerval Zanella
2021-06-17 18:57 ` [PATCH 11/34] Linux: Move aio_cancel, aio_cancel64 " Florian Weimer
2021-06-23 17:26   ` Adhemerval Zanella
2021-06-17 18:57 ` [PATCH 12/34] Linux: Move aio_error, aio_error64 " Florian Weimer
2021-06-23 17:43   ` Adhemerval Zanella
2021-06-17 18:57 ` [PATCH 13/34] Linux: Move aio_fsync, aio_fsync64 " Florian Weimer
2021-06-23 17:46   ` Adhemerval Zanella
2021-06-17 18:58 ` [PATCH 14/34] Linux: Move aio_read, aio_read64 " Florian Weimer
2021-06-23 17:51   ` Adhemerval Zanella
2021-06-25  9:53     ` Florian Weimer
2021-06-25 12:36       ` Adhemerval Zanella
2021-06-17 18:58 ` [PATCH 15/34] Linux: Move aio_return, aio_return64 " Florian Weimer
2021-06-23 19:44   ` Adhemerval Zanella
2021-06-17 18:58 ` [PATCH 16/34] Linux: Move aio_suspend, aio_suspend64, __aio_suspend_time64 to libc Florian Weimer
2021-06-23 19:52   ` Adhemerval Zanella
2021-06-23 19:59     ` Florian Weimer
2021-06-17 18:58 ` [PATCH 17/34] Linux: Move aio_write, aio_write64 into libc Florian Weimer
2021-06-23 20:02   ` Adhemerval Zanella
2021-06-17 18:58 ` [PATCH 18/34] rt: Rework lio_listio implementation Florian Weimer
2021-06-23 20:10   ` Adhemerval Zanella
2021-06-17 18:58 ` [PATCH 19/34] Linux: Move lio_listio, lio_listio64 from librt to libc Florian Weimer
2021-06-23 20:12   ` Adhemerval Zanella
2021-06-17 18:58 ` [PATCH 20/34] Linux: Move mq_close " Florian Weimer
2021-06-24 14:00   ` Adhemerval Zanella
2021-06-17 18:58 ` [PATCH 21/34] Linux: Move mq_setattr " Florian Weimer
2021-06-24 14:02   ` Adhemerval Zanella
2021-06-25 10:02     ` Florian Weimer
2021-06-17 18:58 ` [PATCH 22/34] Linux: Move mq_getattr " Florian Weimer
2021-06-24 14:02   ` Adhemerval Zanella
2021-06-17 18:58 ` [PATCH 23/34] Linux: Move mq_notify " Florian Weimer
2021-06-24 14:05   ` Adhemerval Zanella
2021-06-25 11:37     ` Florian Weimer
2021-06-17 18:59 ` [PATCH 24/34] Linux: Move mq_open, __mq_open_2 " Florian Weimer
2021-06-24 14:07   ` Adhemerval Zanella
2021-06-17 18:59 ` [PATCH 25/34] Linux: Move mq_receive, mq_timedreceive, __mq_timedreceive_time64 " Florian Weimer
2021-06-24 14:14   ` Adhemerval Zanella
2021-06-17 18:59 ` [PATCH 26/34] Linux: Move mq_send, mq_timedsend, __mq_timedsend_time64 " Florian Weimer
2021-06-24 14:22   ` Adhemerval Zanella
2021-06-17 18:59 ` [PATCH 27/34] Linux: Move mq_unlink from librt " Florian Weimer
2021-06-24 14:31   ` Adhemerval Zanella
2021-06-17 18:59 ` [PATCH 28/34] Linux: Move timer helper routines " Florian Weimer
2021-06-24 14:41   ` Adhemerval Zanella [this message]
2021-06-25 11:38     ` Florian Weimer
2021-06-17 18:59 ` [PATCH 29/34] Linux: Define TIMER_T_WAS_INT_COMPAT in kernel-posix-timers.h Florian Weimer
2021-06-24 16:21   ` Adhemerval Zanella
2021-06-17 18:59 ` [PATCH 30/34] Linux: Move timer_create, timer_delete from librt to libc Florian Weimer
2021-06-24 17:18   ` Adhemerval Zanella
2021-06-17 18:59 ` [PATCH 31/34] Linux: Move timer_getoverrun " Florian Weimer
2021-06-24 17:26   ` Adhemerval Zanella
2021-06-24 17:38   ` Adhemerval Zanella
2021-06-17 18:59 ` [PATCH 32/34] Linux: Move timer_gettime, __timer_gettime64 " Florian Weimer
2021-06-24 17:36   ` Adhemerval Zanella
2021-06-17 18:59 ` [PATCH 33/34] Linux: Move timer_settime, __timer_settime64 " Florian Weimer
2021-06-24 17:42   ` Adhemerval Zanella
2021-06-17 19:00 ` [PATCH 34/34] Linux: Cleanups after librt move Florian Weimer
2021-06-24 17:45   ` Adhemerval Zanella
2021-06-25  8:53     ` Florian Weimer
2021-06-24 17:49 ` [PATCH v2 00/34] Move librt into libc Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=685c2e51-f9d9-d93d-9fd5-1906a8efc490@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).