[PATCH] Add and use _REENT_GLOBAL_ATEXIT0
Sebastian Huber
sebastian.huber@embedded-brains.de
Wed May 1 08:46:00 GMT 2013
This patch adds a new define _REENT_GLOBAL_ATEXIT0 which will remove the
_atexit0 field of struct _reent. A global variable defined in
__atexit.c will be used to store the first 32 atexit() handlers. This
option is interesting for all targets which don't care about binary
compatibility and want to save approximately 400 bytes per struct
_reent.
newlib/ChangeLog
2013-05-01 Sebastian Huber <sebastian.huber@embedded-brains.de>
* libc/include/sys/config.h (_REENT_GLOBAL_ATEXIT0): Define for
RTEMS.
* libc/include/sys/reent.h (_ATEXIT_INIT): Define.
(_ATEXIT_INIT_PTR): Likewise.
(_REENT_INIT_ATEXIT0): Likewise.
(_REENT_INIT_ATEXIT0_PTR): Likewise.
(struct _reent): Remove _atexit0 field if _REENT_GLOBAL_ATEXIT0
is defined.
* libc/reent/reent.c (_reclaim_reent): Restructure atexit free
loop.
* libc/stdlib/__atexit.c (_global_atexit0): Define if
_REENT_GLOBAL_ATEXIT0 is defined.
(_REENT_ATEXIT0): Define.
(__register_exitproc): Use _REENT_ATEXIT0.
---
newlib/libc/include/sys/config.h | 1 +
newlib/libc/include/sys/reent.h | 34 ++++++++++++++++++++++++++++------
newlib/libc/reent/reent.c | 27 +++++++++++++++++----------
newlib/libc/stdlib/__atexit.c | 9 ++++++++-
4 files changed, 54 insertions(+), 17 deletions(-)
diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
index a6528b8..4f2c555 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_ATEXIT0
#endif
#ifndef __EXPORT
diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h
index ff0242e..9336d02 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,21 @@ 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_ATEXIT0
+# define _REENT_INIT_ATEXIT0
+# define _REENT_INIT_ATEXIT0_PTR(var)
+#else
+# define _REENT_INIT_ATEXIT0 _ATEXIT_INIT,
+# define _REENT_INIT_ATEXIT0_PTR(var) _ATEXIT_INIT_PTR(var);
#endif
/*
@@ -394,7 +415,9 @@ struct _reent
/* atexit stuff */
struct _atexit *_atexit;
+# ifndef _REENT_GLOBAL_ATEXIT0
struct _atexit _atexit0;
+# endif
struct _glue __sglue; /* root of glue chain */
__FILE *__sf; /* file descriptors */
@@ -426,7 +449,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
_NULL, \
_NULL, \
_NULL, \
- {_NULL, 0, {_NULL}, _NULL}, \
+ _REENT_INIT_ATEXIT0 \
{_NULL, 0, _NULL}, \
_NULL, \
_NULL, \
@@ -453,10 +476,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
(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_ATEXIT0_PTR(&(var)->_atexit0) \
(var)->__sglue._next = _NULL; \
(var)->__sglue._niobs = 0; \
(var)->__sglue._iobs = _NULL; \
@@ -643,7 +663,9 @@ struct _reent
/* atexit stuff */
struct _atexit *_atexit; /* points to head of LIFO stack */
+# ifndef _REENT_GLOBAL_ATEXIT0
struct _atexit _atexit0; /* one guaranteed table, required by ANSI */
+# endif
/* signal info */
void (**(_sig_func))(int);
@@ -699,7 +721,7 @@ struct _reent
} \
}, \
_NULL, \
- {_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}}, \
+ _REENT_INIT_ATEXIT0 \
_NULL, \
{_NULL, 0, _NULL} \
}
diff --git a/newlib/libc/reent/reent.c b/newlib/libc/reent/reent.c
index 63812db..2659061 100644
--- a/newlib/libc/reent/reent.c
+++ b/newlib/libc/reent/reent.c
@@ -91,16 +91,23 @@ _DEFUN (_reclaim_reent, (ptr),
_free_r (ptr, ptr->_atexit->_on_exit_args_ptr);
#else
/* atexit stuff */
- if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))
- {
- struct _atexit *p, *q;
- for (p = ptr->_atexit; p != &ptr->_atexit0;)
- {
- q = p;
- p = p->_next;
- _free_r (ptr, q);
- }
- }
+ {
+ struct _atexit *ae = ptr->_atexit;
+
+ /* Free blocks except the last one, which is part of another
+ entity. */
+ while (ae)
+ {
+ struct _atexit *nae = ae->_next;
+
+ if (nae)
+ {
+ _free_r (ptr, ae);
+ }
+
+ ae = nae;
+ }
+ }
#endif
if (ptr->_cvtbuf)
diff --git a/newlib/libc/stdlib/__atexit.c b/newlib/libc/stdlib/__atexit.c
index 4687d00..d38bb10 100644
--- a/newlib/libc/stdlib/__atexit.c
+++ b/newlib/libc/stdlib/__atexit.c
@@ -12,6 +12,13 @@
void * malloc(size_t) _ATTRIBUTE((__weak__));
__LOCK_INIT_RECURSIVE(, __atexit_lock);
+#ifdef _REENT_GLOBAL_ATEXIT0
+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.
*/
@@ -33,7 +40,7 @@ _DEFUN (__register_exitproc,
p = _GLOBAL_REENT->_atexit;
if (p == NULL)
- _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
+ _GLOBAL_REENT->_atexit = p = _REENT_ATEXIT0(_GLOBAL_REENT);
if (p->_ind >= _ATEXIT_SIZE)
{
#ifndef _ATEXIT_DYNAMIC_ALLOC
--
1.7.10.4
More information about the Newlib
mailing list