RFA: Reducing the size of struct _reent by not supporting on_exit()

J. Johnston jjohnstn@redhat.com
Fri Jun 6 15:39:00 GMT 2003


Nick Clifton wrote:
> Hi Jeff,
> 
> 
>>Better.  Have you considered making the atexit function list also
>>dynamic?
> 
> 
> Yes - but that would break POSIX conformance.  Something I did not
> want to do.
> 
> 
>>If you are keen to save 128 bytes for an application not using
>>on_exit, then it kind of makes sense not to allocate the array for
>>atexit functions unless atexit() gets called.
> 
> 
> I have suggested this to Sanyo, but so far they are not too keen on
> the idea.  I think that the savings in making the on_exit() support
> dynamic are enough for them.
> 
> 
Fair enough.

> 
>>I also have a few minor comments.  There appears to be a few coding indentation
>>mixups in the patch below.  It might be caused by tabs, but please verify
>>that your code is correct (a number of returns after if statements are incorrect).
> 
> 
> Yeah this was just a tab vs whitespace issue.  I have fixed the patch
> to use whitespace throughout.
> 
> 
> 
>>In exit.c, if you are going to code a "for statement" in a macro,
>>then I would like to see you bracket the statements below the macro
>>usage and use indentation so it is clear what code is running inside
>>it.
> 
> 
> Actually I have reconsidered the use of the macro and I now think that
> it was a bad idea.
> 
> Here is a revised patch with all of the above issues addressed.  Is
> this one ready for committing ?
> 

Yes, please go ahead.

-- Jeff J.

> Cheers
>         Nick
> 
> 2003-06-05  Nick Clifton  <nickc@redhat.com>
> 	* libc/include/sys/reent.h (struct _on_exit_args): New
> 	structure containing fields used by the on_exit() function.
>         (struct _atexit): Include struct _on_exit_args.  For
> 	_REENT_SMALL do his via a pointer that is initialised when
> 	needed.
>         * libc/reent/reent.c (_reclaim_reent): Free the _on_exit_args
> 	structure, if one has been allocated.
>         * libc/stdlib/atexit.c (atexit): Update indirection to
> 	_fntypes field.
>         * libc/stdlib/on_exit.c (on_exit): Indirect via the
> 	_on_exit_args structure.  For _REENT_SMALL, allocate a
> 	structure if one does not exist.
>         * libc/stdlib/exit.c (exit): Indirect via the _on_exit_args
> 	structure.
>                 
> 
> Index: libc/include/sys/reent.h
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/include/sys/reent.h,v
> retrieving revision 1.22
> diff -c -3 -p -r1.22 reent.h
> *** libc/include/sys/reent.h	7 Mar 2003 15:56:49 -0000	1.22
> --- libc/include/sys/reent.h	6 Jun 2003 09:35:03 -0000
> *************** struct __tm
> *** 64,83 ****
>   
>   #define	_ATEXIT_SIZE 32	/* must be at least 32 to guarantee ANSI conformance */
>   
> ! #ifndef _REENT_SMALL
>   struct _atexit {
> - 	struct	_atexit *_next;			/* next in list */
>   	int	_ind;				/* next index in this table */
>   	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */
> ! 	void	*_fnargs[_ATEXIT_SIZE];	        /* fn args for on_exit */
> ! 	__ULong _fntypes;           	        /* type of exit routine */
>   };
>   #else
>   struct _atexit {
>   	int	_ind;				/* next index in this table */
>   	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */
> ! 	void	*_fnargs[_ATEXIT_SIZE];	        /* fn args for on_exit */
> ! 	__ULong _fntypes;           	        /* type of exit routine */
>   };
>   #endif
>   
> --- 64,87 ----
>   
>   #define	_ATEXIT_SIZE 32	/* must be at least 32 to guarantee ANSI conformance */
>   
> ! struct _on_exit_args {
> ! 	void *  _fnargs[_ATEXIT_SIZE];	        /* fn args for on_exit */
> ! 	__ULong _fntypes;           	        /* type of exit routine -
> ! 						   Must have at least _ATEXIT_SIZE bits */
> ! };
> ! 
> ! #ifdef _REENT_SMALL
>   struct _atexit {
>   	int	_ind;				/* next index in this table */
>   	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */
> !         struct _on_exit_args * _on_exit_args_ptr;
>   };
>   #else
>   struct _atexit {
> + 	struct	_atexit *_next;			/* next in list */
>   	int	_ind;				/* next index in this table */
>   	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */
> !         struct _on_exit_args _on_exit_args;
>   };
>   #endif
>   
> Index: libc/reent/reent.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/reent/reent.c,v
> retrieving revision 1.5
> diff -c -3 -p -r1.5 reent.c
> *** libc/reent/reent.c	3 Jun 2003 19:48:07 -0000	1.5
> --- libc/reent/reent.c	6 Jun 2003 09:35:06 -0000
> *************** _DEFUN (_reclaim_reent, (ptr),
> *** 81,86 ****
> --- 81,88 ----
>   	_free_r (ptr, ptr->_localtime_buf);
>         if (ptr->_asctime_buf)
>   	_free_r (ptr, ptr->_asctime_buf);
> +       if (ptr->_atexit._on_exit_args_ptr)
> + 	_free_r (ptr->_atexit._on_exit_args_ptr);
>   #else
>         /* atexit stuff */
>         if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))
> Index: libc/stdlib/atexit.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/atexit.c,v
> retrieving revision 1.3
> diff -c -3 -p -r1.3 atexit.c
> *** libc/stdlib/atexit.c	15 May 2002 22:58:10 -0000	1.3
> --- libc/stdlib/atexit.c	6 Jun 2003 09:35:08 -0000
> *************** _DEFUN (atexit,
> *** 65,80 ****
>   {
>     register struct _atexit *p;
>   
> ! /* _REENT_SMALL atexit() doesn't allow more than the required 32 entries.  */
>   #ifndef _REENT_SMALL
>     if ((p = _REENT->_atexit) == NULL)
>       _REENT->_atexit = p = &_REENT->_atexit0;
>     if (p->_ind >= _ATEXIT_SIZE)
>       {
>         if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
> ! 	return -1;
>         p->_ind = 0;
> !       p->_fntypes = 0;
>         p->_next = _REENT->_atexit;
>         _REENT->_atexit = p;
>       }
> --- 65,80 ----
>   {
>     register struct _atexit *p;
>   
> !   /* _REENT_SMALL atexit() doesn't allow more than the required 32 entries.  */
>   #ifndef _REENT_SMALL
>     if ((p = _REENT->_atexit) == NULL)
>       _REENT->_atexit = p = &_REENT->_atexit0;
>     if (p->_ind >= _ATEXIT_SIZE)
>       {
>         if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
> !         return -1;
>         p->_ind = 0;
> !       p->_on_exit_args._fntypes = 0;
>         p->_next = _REENT->_atexit;
>         _REENT->_atexit = p;
>       }
> Index: libc/stdlib/exit.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/exit.c,v
> retrieving revision 1.3
> diff -c -3 -p -r1.3 exit.c
> *** libc/stdlib/exit.c	15 May 2002 22:58:10 -0000	1.3
> --- libc/stdlib/exit.c	6 Jun 2003 09:35:08 -0000
> *************** _DEFUN (exit, (code),
> *** 60,79 ****
>   	int code)
>   {
>     register struct _atexit *p;
>     register int n;
> !   int i = 1;
>   
>   #ifdef _REENT_SMALL
> !   for (p = &_REENT->_atexit, n = p->_ind-1, i = (n>=0) ? (1<<n) : 0; 
> !        n >= 0; --n, i >>= 1)
>   #else
> !   for (p = _REENT->_atexit; p; p = p->_next)
> !     for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
>   #endif
> -       if (p->_fntypes & i)
> -         (*((void (*)(int, void *))p->_fns[n]))(code, p->_fnargs[n]);
> -       else
> -         (*p->_fns[n]) ();
>   
>     if (_REENT->__cleanup)
>       (*_REENT->__cleanup) (_REENT);
> --- 60,102 ----
>   	int code)
>   {
>     register struct _atexit *p;
> +   register struct _on_exit_args * args;
>     register int n;
> !   int i;
> ! 
> !   p = &_REENT->_atexit;
>   
>   #ifdef _REENT_SMALL
> !   args = p->_on_exit_args_ptr;
> !   
> !   if (args == NULL)
> !     {
> !       for (n = p->_ind; n--;)
> !         p->_fns[n] ();
> !     }
> !   else
> !     {
> !       for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
> !         if (args->_fntypes & i)
> !           (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]);
> !         else
> !           p->_fns[n] ();
> !     }
>   #else
> !   do
> !     {
> !       args = & p->_on_exit_args;
> !   
> !       for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
> !         if (args->_fntypes & i)
> !           (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]);
> !         else
> !           p->_fns[n] ();
> ! 
> !       p = p->_next;
> !     }
> !   while (p);
>   #endif
>   
>     if (_REENT->__cleanup)
>       (*_REENT->__cleanup) (_REENT);
> Index: libc/stdlib/on_exit.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/on_exit.c,v
> retrieving revision 1.1
> diff -c -3 -p -r1.1 on_exit.c
> *** libc/stdlib/on_exit.c	15 May 2002 22:58:10 -0000	1.1
> --- libc/stdlib/on_exit.c	6 Jun 2003 09:35:08 -0000
> *************** _DEFUN (on_exit,
> *** 68,96 ****
>   	_VOID _EXFUN ((*fn), (int, _PTR)) _AND
>           _PTR arg)
>   {
>     register struct _atexit *p;
>     void (*x)(void) = (void (*)(void))fn;
>   
>   /* _REENT_SMALL on_exit() doesn't allow more than the required 32 entries.  */
> ! #ifndef _REENT_SMALL
>     if ((p = _REENT->_atexit) == NULL)
>       _REENT->_atexit = p = &_REENT->_atexit0;
>     if (p->_ind >= _ATEXIT_SIZE)
>       {
>         if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
> ! 	return -1;
>         p->_ind = 0;
> !       p->_fntypes = 0;
>         p->_next = _REENT->_atexit;
>         _REENT->_atexit = p;
>       }
> ! #else
> !   p = &_REENT->_atexit;
> !   if (p->_ind >= _ATEXIT_SIZE)
> !     return -1;
>   #endif
> !   p->_fntypes |= (1 << p->_ind);
> !   p->_fnargs[p->_ind] = arg;
>     p->_fns[p->_ind++] = x;
>     return 0;
>   }
> --- 68,107 ----
>   	_VOID _EXFUN ((*fn), (int, _PTR)) _AND
>           _PTR arg)
>   {
> +   struct _on_exit_args * args;
>     register struct _atexit *p;
>     void (*x)(void) = (void (*)(void))fn;
>   
>   /* _REENT_SMALL on_exit() doesn't allow more than the required 32 entries.  */
> ! #ifdef _REENT_SMALL
> !   p = &_REENT->_atexit;
> !   if (p->_ind >= _ATEXIT_SIZE)
> !     return -1;
> !   args = p->_on_exit_args_ptr;
> !   if (args == NULL)
> !     {
> !       args = malloc (sizeof * p->_on_exit_args_ptr);
> !       if (args == NULL)
> !         return -1;
> !       args->_fntypes = 0;
> !       p->_on_exit_args_ptr = args;
> !     }
> ! #else
>     if ((p = _REENT->_atexit) == NULL)
>       _REENT->_atexit = p = &_REENT->_atexit0;
>     if (p->_ind >= _ATEXIT_SIZE)
>       {
>         if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
> !         return -1;
>         p->_ind = 0;
> !       p->_on_exit_args._fntypes = 0;
>         p->_next = _REENT->_atexit;
>         _REENT->_atexit = p;
>       }
> !   args = & p->_on_exit_args;
>   #endif
> !   args->_fntypes |= (1 << p->_ind);
> !   args->_fnargs[p->_ind] = arg;
>     p->_fns[p->_ind++] = x;
>     return 0;
>   }
> 




More information about the Newlib mailing list