This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: Reducing the size of struct _reent by not supportingon_exit()


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.


> 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 ?

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;
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]