RFA: Reducing the size of struct _reent by not supporting on_exit()
Nick Clifton
nickc@redhat.com
Fri Jun 6 15:32:00 GMT 2003
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;
}
More information about the Newlib
mailing list