[PATCH 2/2] Add and use _REENT_GLOBAL_ATEXIT

Joel Sherrill joel.sherrill@oarcorp.com
Tue May 7 21:36:00 GMT 2013


First, I am thrilled to see the reent structure shrinking.

But binary compatibility has been mentioned.
Binary compatibility with what?  What targets?

Except for Cygwin and Linux, I would think most users are
compiling from source. And even if not, I wouldn't think it
was cool to directly access the reent structure anyway. If
we added, deleted or reordered the fields, things would break.

Just curious what this use case is.

Thanks.

--joel


On 5/7/2013 3:42 PM, Sebastian Huber wrote:
> This patch adds a new define _REENT_GLOBAL_ATEXIT which will remove the
> atexit fields of struct _reent.  A global variable defined in __atexit.c
> will be used to store the first 32 atexit() handlers.  A global variable
> in __call_atexit.c contains the LIFO head.  This option is interesting
> for all targets which don't care about binary compatibility and want to
> save approximately 400 bytes per struct _reent.
>
> newlib/ChangeLog
> 2013-05-07  Sebastian Huber <sebastian.huber@embedded-brains.de>
>
> 	* libc/include/sys/config.h (_REENT_GLOBAL_ATEXIT): Define for
> 	RTEMS.
> 	* libc/include/sys/reent.h (_reent): Use _REENT_GLOBAL_ATEXIT.
> 	(_global_atexit): Declare if _REENT_GLOBAL_ATEXIT is defined.
> 	* libc/reent/reent.c (_reclaim_reent): Remove atexit cleanup if
> 	_REENT_GLOBAL_ATEXIT is defined.
> 	(_wrapup_reent): Remove atexit handling if _REENT_GLOBAL_ATEXIT
> 	is defined.
> 	* libc/stdlib/__atexit.c (_global_atexit0): Define if
> 	_REENT_GLOBAL_ATEXIT is defined.
> 	* libc/stdlib/__call_atexit.c (_global_atexit): Define if
> 	_REENT_GLOBAL_ATEXIT is defined.
> ---
>   newlib/libc/include/sys/config.h   |    1 +
>   newlib/libc/include/sys/reent.h    |   20 +++++++++++++++++---
>   newlib/libc/reent/reent.c          |   17 +++++++++++++----
>   newlib/libc/stdlib/__atexit.c      |    7 ++++++-
>   newlib/libc/stdlib/__call_atexit.c |    4 ++++
>   5 files changed, 41 insertions(+), 8 deletions(-)
>
> diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
> index a6528b8..b26017b 100644
> --- a/newlib/libc/include/sys/config.h
> +++ b/newlib/libc/include/sys/config.h
> @@ -217,6 +217,7 @@
>   #if defined(__rtems__)
>   #define __FILENAME_MAX__ 255
>   #define _READ_WRITE_RETURN_TYPE _ssize_t
> +#define _REENT_GLOBAL_ATEXIT
>   #endif
>   
>   #ifndef __EXPORT
> diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h
> index 8b78f5b..21f02cc 100644
> --- a/newlib/libc/include/sys/reent.h
> +++ b/newlib/libc/include/sys/reent.h
> @@ -108,10 +108,15 @@ struct _atexit {
>     (var)->_on_exit_args._fnargs[0] = _NULL
>   #endif
>   
> -#define _REENT_INIT_ATEXIT \
> +#ifdef _REENT_GLOBAL_ATEXIT
> +# define _REENT_INIT_ATEXIT
> +# define _REENT_INIT_ATEXIT_PTR(var, var0)
> +#else
> +# define _REENT_INIT_ATEXIT \
>     _NULL, _ATEXIT_INIT,
> -#define _REENT_INIT_ATEXIT_PTR(var, var0) \
> +# define _REENT_INIT_ATEXIT_PTR(var, var0) \
>     (var)->_atexit = _NULL; _ATEXIT_INIT_PTR(var0);
> +#endif
>   
>   /*
>    * Stdio buffers.
> @@ -410,9 +415,11 @@ struct _reent
>     /* signal info */
>     void (**(_sig_func))(int);
>   
> +# ifndef _REENT_GLOBAL_ATEXIT
>     /* atexit stuff */
>     struct _atexit *_atexit;
>     struct _atexit _atexit0;
> +# endif
>   
>     struct _glue __sglue;			/* root of glue chain */
>     __FILE *__sf;			        /* file descriptors */
> @@ -654,9 +661,11 @@ struct _reent
>           } _unused;
>       } _new;
>   
> +# ifndef _REENT_GLOBAL_ATEXIT
>     /* atexit stuff */
>     struct _atexit *_atexit;	/* points to head of LIFO stack */
>     struct _atexit _atexit0;	/* one guaranteed table, required by ANSI */
> +# endif
>   
>     /* signal info */
>     void (**(_sig_func))(int);
> @@ -803,7 +812,12 @@ void _reclaim_reent _PARAMS ((struct _reent *));
>   
>   #define _GLOBAL_REENT _global_impure_ptr
>   
> -#define _GLOBAL_ATEXIT (_GLOBAL_REENT->_atexit)
> +#ifdef _REENT_GLOBAL_ATEXIT
> +extern struct _atexit *_global_atexit; /* points to head of LIFO stack */
> +# define _GLOBAL_ATEXIT _global_atexit
> +#else
> +# define _GLOBAL_ATEXIT (_GLOBAL_REENT->_atexit)
> +#endif
>   
>   #ifdef __cplusplus
>   }
> diff --git a/newlib/libc/reent/reent.c b/newlib/libc/reent/reent.c
> index 63812db..61da3b2 100644
> --- a/newlib/libc/reent/reent.c
> +++ b/newlib/libc/reent/reent.c
> @@ -87,10 +87,14 @@ _DEFUN (_reclaim_reent, (ptr),
>   	_free_r (ptr, ptr->_localtime_buf);
>         if (ptr->_asctime_buf)
>   	_free_r (ptr, ptr->_asctime_buf);
> +#endif
> +
> +#ifndef _REENT_GLOBAL_ATEXIT
> +      /* atexit stuff */
> +# ifdef _REENT_SMALL
>         if (ptr->_atexit && ptr->_atexit->_on_exit_args_ptr)
>   	_free_r (ptr, ptr->_atexit->_on_exit_args_ptr);
> -#else
> -      /* atexit stuff */
> +# else
>         if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))
>   	{
>   	  struct _atexit *p, *q;
> @@ -101,6 +105,7 @@ _DEFUN (_reclaim_reent, (ptr),
>   	      _free_r (ptr, q);
>   	    }
>   	}
> +# endif
>   #endif
>   
>         if (ptr->_cvtbuf)
> @@ -131,19 +136,23 @@ _DEFUN (_reclaim_reent, (ptr),
>   void
>   _DEFUN (_wrapup_reent, (ptr), struct _reent *ptr)
>   {
> +#ifndef _REENT_GLOBAL_ATEXIT
>     register struct _atexit *p;
> +#endif
>     register int n;
>   
>     if (ptr == NULL)
>       ptr = _REENT;
>   
> -#ifdef _REENT_SMALL
> +#ifndef _REENT_GLOBAL_ATEXIT
> +# ifdef _REENT_SMALL
>     for (p = ptr->_atexit, n = p ? p->_ind : 0; --n >= 0;)
>       (*p->_fns[n]) ();
> -#else
> +# else
>     for (p = ptr->_atexit; p; p = p->_next)
>       for (n = p->_ind; --n >= 0;)
>         (*p->_fns[n]) ();
> +# endif
>   #endif
>     if (ptr->__cleanup)
>       (*ptr->__cleanup) (ptr);
> diff --git a/newlib/libc/stdlib/__atexit.c b/newlib/libc/stdlib/__atexit.c
> index a095313..f04f00d 100644
> --- a/newlib/libc/stdlib/__atexit.c
> +++ b/newlib/libc/stdlib/__atexit.c
> @@ -15,7 +15,12 @@ void * malloc(size_t) _ATTRIBUTE((__weak__));
>   extern _LOCK_RECURSIVE_T __atexit_lock;
>   #endif
>   
> -#define _GLOBAL_ATEXIT0 (&_GLOBAL_REENT->_atexit0)
> +#ifdef _REENT_GLOBAL_ATEXIT
> +static struct _atexit _global_atexit0 = _ATEXIT_INIT;
> +# define _GLOBAL_ATEXIT0 (&_global_atexit0)
> +#else
> +# define _GLOBAL_ATEXIT0 (&_GLOBAL_REENT->_atexit0)
> +#endif
>   
>   /*
>    * Register a function to be performed at exit or on shared library unload.
> diff --git a/newlib/libc/stdlib/__call_atexit.c b/newlib/libc/stdlib/__call_atexit.c
> index 76d3f12..1e6e710 100644
> --- a/newlib/libc/stdlib/__call_atexit.c
> +++ b/newlib/libc/stdlib/__call_atexit.c
> @@ -13,6 +13,10 @@ void free(void *) _ATTRIBUTE((__weak__));
>   
>   __LOCK_INIT_RECURSIVE(, __atexit_lock);
>   
> +#ifdef _REENT_GLOBAL_ATEXIT
> +struct _atexit *_global_atexit = _NULL;
> +#endif
> +
>   #ifdef _WANT_REGISTER_FINI
>   
>   /* If "__libc_fini" is defined, finalizers (either


-- 
Joel Sherrill, Ph.D.             Director of Research & Development
joel.sherrill@OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
Support Available                (256) 722-9985



More information about the Newlib mailing list