This is the mail archive of the newlib@sourceware.org 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]

[PATCH] Add and use _REENT_GLOBAL_ATEXIT0


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


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