[PATCH] Add and use _REENT_GLOBAL_ATEXIT

Jeff Johnston jjohnstn@redhat.com
Thu May 2 19:36:00 GMT 2013


I would like to change this.

I don't like having a macro that takes a ptr argument and ignores it.  I 
also would prefer consistency with the impure ptr struct declarations. 
The atexit0 storage is supposed to be statically guaranteed which is 
currently accomplished by being part of the static global reent struct.

My preference is that you declare a static atexit0_data struct inside 
impure.c along-side the impure_data declaration (being controlled by 
your new _REENT_GLOBAL_ATEXIT macro).

Then, you have two macros:

_GLOBAL_ATEXIT  (which is either _GLOBAL_REENT->_atexit or 
_impure_atexit (whatever you call it), which is also declared in 
impure.c based on the _REENT_GLOBAL_ATEXIT macro.

and

_GLOBAL_ATEXIT0 (which is either &(_GLOBAL_REENT->_atexit0) or the 
address of _impure_atexit0_data or whatever you put in impure.c for 
atexit0).

It becomes relatively straightforward after that to change the existing 
code.

I probably would not have bothered moving the _atexit pointer out of the 
struct myself since it is such a minor gain compared to the atexit0 
savings but whatever.

-- Jeff J.



On 05/01/2013 11:58 AM, Sebastian Huber wrote:
> This patch adds a new define _REENT_GLOBAL_ATEXIT which will remove the
> _atexit and _atexit0 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.
>
> The usage of __register_exitproc() will pull in also __call_atexit.c but
> not vice versa.
>
> newlib/ChangeLog
> 2013-05-01  Sebastian Huber <sebastian.huber@embedded-brains.de>
>
> 	* libc/include/sys/config.h (_REENT_GLOBAL_ATEXIT): Define for
> 	RTEMS.
> 	* libc/include/sys/reent.h (_ATEXIT_INIT): Define.
> 	(_ATEXIT_INIT_PTR): Likewise.
> 	(_REENT_INIT_ATEXIT): Likewise.
> 	(_REENT_INIT_ATEXIT_PTR): Likewise.
> 	(_REENT_ATEXIT): Likewise.
> 	(struct _reent): Remove _atexit and _atexit0 fields if
> 	_REENT_GLOBAL_ATEXIT is defined.
> 	(_global_atexit): Declare if _REENT_GLOBAL_ATEXIT is defined.
> 	* libc/reent/reent.c (_reclaim_reent): Use _REENT_GLOBAL_ATEXIT.
> 	(_wrapup_reent): Likewise.
> 	* libc/stdlib/__atexit.c (__atexit_lock): Declare.
> 	(_global_atexit0): Define if _REENT_GLOBAL_ATEXIT is defined.
> 	(_REENT_ATEXIT0): Define.
> 	(__register_exitproc): Use _REENT_ATEXIT and _REENT_ATEXIT0.
> 	* libc/stdlib/__call_atexit.c (__atexit_lock): Define.
> 	(_global_atexit): Define if _REENT_GLOBAL_ATEXIT is defined.
> 	(__call_exitprocs): Use _REENT_ATEXIT.
> ---
>   newlib/libc/include/sys/config.h   |    1 +
>   newlib/libc/include/sys/reent.h    |   46 +++++++++++++++++++++++++++++-------
>   newlib/libc/reent/reent.c          |   17 +++++++++----
>   newlib/libc/stdlib/__atexit.c      |   20 ++++++++++++----
>   newlib/libc/stdlib/__call_atexit.c |   10 ++++----
>   5 files changed, 72 insertions(+), 22 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 ff0242e..e3120a0 100644
> --- a/newlib/libc/include/sys/reent.h
> +++ b/newlib/libc/include/sys/reent.h
> @@ -85,6 +85,12 @@ struct _atexit {
>   	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */
>           struct _on_exit_args * _on_exit_args_ptr;
>   };
> +# define _ATEXIT_INIT {_NULL, 0, {_NULL}, _NULL}
> +# define _ATEXIT_INIT_PTR(var) \
> +  (var)->_next = _NULL; \
> +  (var)->_ind = 0; \
> +  (var)->_fns[0] = _NULL; \
> +  (var)->_on_exit_args_ptr = _NULL
>   #else
>   struct _atexit {
>   	struct	_atexit *_next;			/* next in list */
> @@ -93,6 +99,23 @@ struct _atexit {
>   	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */
>           struct _on_exit_args _on_exit_args;
>   };
> +# define _ATEXIT_INIT {_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}}
> +# define _ATEXIT_INIT_PTR(var) \
> +  (var)->_next = _NULL; \
> +  (var)->_ind = 0; \
> +  (var)->_fns[0] = _NULL; \
> +  (var)->_on_exit_args._fntypes = 0; \
> +  (var)->_on_exit_args._fnargs[0] = _NULL
> +#endif
> +
> +#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) \
> +  (var)->_atexit = _NULL; _ATEXIT_INIT_PTR(var0);
>   #endif
>
>   /*
> @@ -392,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 */
> @@ -425,8 +450,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
>       _NULL, \
>       _NULL, \
>       _NULL, \
> -    _NULL, \
> -    {_NULL, 0, {_NULL}, _NULL}, \
> +    _REENT_INIT_ATEXIT \
>       {_NULL, 0, _NULL}, \
>       _NULL, \
>       _NULL, \
> @@ -452,11 +476,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
>       (var)->_localtime_buf = _NULL; \
>       (var)->_asctime_buf = _NULL; \
>       (var)->_sig_func = _NULL; \
> -    (var)->_atexit = _NULL; \
> -    (var)->_atexit0._next = _NULL; \
> -    (var)->_atexit0._ind = 0; \
> -    (var)->_atexit0._fns[0] = _NULL; \
> -    (var)->_atexit0._on_exit_args_ptr = _NULL; \
> +    _REENT_INIT_ATEXIT_PTR(var, &(var)->_atexit0) \
>       (var)->__sglue._next = _NULL; \
>       (var)->__sglue._niobs = 0; \
>       (var)->__sglue._iobs = _NULL; \
> @@ -641,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);
> @@ -698,8 +720,7 @@ struct _reent
>           {0, {0}} \
>         } \
>       }, \
> -    _NULL, \
> -    {_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}}, \
> +    _REENT_INIT_ATEXIT \
>       _NULL, \
>       {_NULL, 0, _NULL} \
>     }
> @@ -791,6 +812,13 @@ void _reclaim_reent _PARAMS ((struct _reent *));
>
>   #define _GLOBAL_REENT _global_impure_ptr
>
> +#ifdef _REENT_GLOBAL_ATEXIT
> +extern struct _atexit *_global_atexit; /* points to head of LIFO stack */
> +# define _REENT_ATEXIT(ptr) _global_atexit
> +#else
> +# define _REENT_ATEXIT(ptr) ((ptr)->_atexit)
> +#endif
> +
>   #ifdef __cplusplus
>   }
>   #endif
> 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 4687d00..b8104da 100644
> --- a/newlib/libc/stdlib/__atexit.c
> +++ b/newlib/libc/stdlib/__atexit.c
> @@ -10,7 +10,17 @@
>
>   /* Make this a weak reference to avoid pulling in malloc.  */
>   void * malloc(size_t) _ATTRIBUTE((__weak__));
> -__LOCK_INIT_RECURSIVE(, __atexit_lock);
> +
> +#ifndef __SINGLE_THREAD__
> +extern _LOCK_RECURSIVE_T __atexit_lock;
> +#endif
> +
> +#ifdef _REENT_GLOBAL_ATEXIT
> +static struct _atexit _global_atexit0 = _ATEXIT_INIT;
> +# define _REENT_ATEXIT0(ptr) (&_global_atexit0)
> +#else
> +# define _REENT_ATEXIT0(ptr) (&(ptr)->_atexit0)
> +#endif
>
>   /*
>    * Register a function to be performed at exit or on shared library unload.
> @@ -31,9 +41,9 @@ _DEFUN (__register_exitproc,
>     __lock_acquire_recursive(__atexit_lock);
>   #endif
>
> -  p = _GLOBAL_REENT->_atexit;
> +  p = _REENT_ATEXIT(_GLOBAL_REENT);
>     if (p == NULL)
> -    _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
> +    _REENT_ATEXIT(_GLOBAL_REENT) = p = _REENT_ATEXIT0(_GLOBAL_REENT);
>     if (p->_ind >= _ATEXIT_SIZE)
>       {
>   #ifndef _ATEXIT_DYNAMIC_ALLOC
> @@ -53,8 +63,8 @@ _DEFUN (__register_exitproc,
>   	  return -1;
>   	}
>         p->_ind = 0;
> -      p->_next = _GLOBAL_REENT->_atexit;
> -      _GLOBAL_REENT->_atexit = p;
> +      p->_next = _REENT_ATEXIT(_GLOBAL_REENT);
> +      _REENT_ATEXIT(_GLOBAL_REENT) = p;
>   #ifndef _REENT_SMALL
>         p->_on_exit_args._fntypes = 0;
>         p->_on_exit_args._is_cxa = 0;
> diff --git a/newlib/libc/stdlib/__call_atexit.c b/newlib/libc/stdlib/__call_atexit.c
> index 4c45063..b30b843 100644
> --- a/newlib/libc/stdlib/__call_atexit.c
> +++ b/newlib/libc/stdlib/__call_atexit.c
> @@ -11,8 +11,10 @@
>   /* Make this a weak reference to avoid pulling in free.  */
>   void free(void *) _ATTRIBUTE((__weak__));
>
> -#ifndef __SINGLE_THREAD__
> -extern _LOCK_RECURSIVE_T __atexit_lock;
> +__LOCK_INIT_RECURSIVE(, __atexit_lock);
> +
> +#ifdef _REENT_GLOBAL_ATEXIT
> +struct _atexit *_global_atexit = _NULL;
>   #endif
>
>   #ifdef _WANT_REGISTER_FINI
> @@ -78,8 +80,8 @@ _DEFUN (__call_exitprocs, (code, d),
>
>    restart:
>
> -  p = _GLOBAL_REENT->_atexit;
> -  lastp = &_GLOBAL_REENT->_atexit;
> +  p = _REENT_ATEXIT(_GLOBAL_REENT);
> +  lastp = &_REENT_ATEXIT(_GLOBAL_REENT);
>     while (p)
>       {
>   #ifdef _REENT_SMALL
>



More information about the Newlib mailing list