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,

>> I would think a better tack would be a macro that changes the _fns
>> from being:
>> 	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */
>> to:
>> 	void	**_fns;				/* the table itself */
>> and then allocate it if the user ever needed on_exit functionality.
>> Obviously
>> you would have to check whether it was allocated or not.
>>
>
> I agree.  A dynamic allocation solution makes more sense for both the
> function pointers and the argument list.  If a user doesn't call
> on_exit, then there is no reason to allocate the additional area.  If
> an application needs to use it, there is no reason to fail
> unconditionally.  This fits in with the whole spirit of _REENT_SMALL.

Ok - how about this revised patch then ?  Can I apply this one ?

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: newlib/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
*** newlib/libc/include/sys/reent.h	7 Mar 2003 15:56:49 -0000	1.22
--- newlib/libc/include/sys/reent.h	5 Jun 2003 09:28:35 -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: newlib/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
*** newlib/libc/reent/reent.c	3 Jun 2003 19:48:07 -0000	1.5
--- newlib/libc/reent/reent.c	5 Jun 2003 09:28:35 -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: newlib/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
*** newlib/libc/stdlib/atexit.c	15 May 2002 22:58:10 -0000	1.3
--- newlib/libc/stdlib/atexit.c	5 Jun 2003 09:28:36 -0000
*************** _DEFUN (atexit,
*** 74,80 ****
        if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
  	return -1;
        p->_ind = 0;
!       p->_fntypes = 0;
        p->_next = _REENT->_atexit;
        _REENT->_atexit = p;
      }
--- 74,80 ----
        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: newlib/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
*** newlib/libc/stdlib/on_exit.c	15 May 2002 22:58:10 -0000	1.1
--- newlib/libc/stdlib/on_exit.c	5 Jun 2003 09:28:36 -0000
*************** _DEFUN (on_exit,
*** 68,78 ****
  	_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)
--- 68,92 ----
  	_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)
*************** _DEFUN (on_exit,
*** 80,96 ****
        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;
  }
--- 94,107 ----
        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: newlib/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
*** newlib/libc/stdlib/exit.c	15 May 2002 22:58:10 -0000	1.3
--- newlib/libc/stdlib/exit.c	5 Jun 2003 09:28:36 -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,104 ----
  	int code)
  {
    register struct _atexit *p;
+   register struct _on_exit_args * args;
    register int n;
!   int i;
! 
!   p = &_REENT->_atexit;
! 
! #define WALK_FUNCS       for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
  
  #ifdef _REENT_SMALL
!   args = p->_on_exit_args_ptr;
!   
!   if (args == NULL)
!     {
!       WALK_FUNCS
! 	p->_fns[n] ();
!     }
!   else
!     {
!       WALK_FUNCS
! 	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;
!   
!       WALK_FUNCS
! 	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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]