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_ATEXIT


This patch adds a new define _REENT_GLOBAL_ATEXIT which will remove the
_atexit and _atexit0 fields of struct _reent.  A global variable defined
in __atexit.c will be used to store the first 32 atexit() handlers.  A
global variable in __call_atexit.c contains the LIFO head.  This option
is interesting for all targets which don't care about binary
compatibility and want to save approximately 400 bytes per struct
_reent.

The usage of __register_exitproc() will pull in also __call_atexit.c but
not vice versa.

newlib/ChangeLog
2013-05-01  Sebastian Huber <sebastian.huber@embedded-brains.de>

	* libc/include/sys/config.h (_REENT_GLOBAL_ATEXIT): Define for
	RTEMS.
	* libc/include/sys/reent.h (_ATEXIT_INIT): Define.
	(_ATEXIT_INIT_PTR): Likewise.
	(_REENT_INIT_ATEXIT): Likewise.
	(_REENT_INIT_ATEXIT_PTR): Likewise.
	(_REENT_ATEXIT): Likewise.
	(struct _reent): Remove _atexit and _atexit0 fields if
	_REENT_GLOBAL_ATEXIT is defined.
	(_global_atexit): Declare if _REENT_GLOBAL_ATEXIT is defined.
	* libc/reent/reent.c (_reclaim_reent): Use _REENT_GLOBAL_ATEXIT.
	(_wrapup_reent): Likewise.
	* libc/stdlib/__atexit.c (__atexit_lock): Declare.
	(_global_atexit0): Define if _REENT_GLOBAL_ATEXIT is defined.
	(_REENT_ATEXIT0): Define.
	(__register_exitproc): Use _REENT_ATEXIT and _REENT_ATEXIT0.
	* libc/stdlib/__call_atexit.c (__atexit_lock): Define.
	(_global_atexit): Define if _REENT_GLOBAL_ATEXIT is defined.
	(__call_exitprocs): Use _REENT_ATEXIT.
---
 newlib/libc/include/sys/config.h   |    1 +
 newlib/libc/include/sys/reent.h    |   46 +++++++++++++++++++++++++++++-------
 newlib/libc/reent/reent.c          |   17 +++++++++----
 newlib/libc/stdlib/__atexit.c      |   20 ++++++++++++----
 newlib/libc/stdlib/__call_atexit.c |   10 ++++----
 5 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
index a6528b8..b26017b 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_ATEXIT
 #endif
 
 #ifndef __EXPORT
diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h
index ff0242e..e3120a0 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,23 @@ 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_ATEXIT
+# define _REENT_INIT_ATEXIT
+# define _REENT_INIT_ATEXIT_PTR(var, var0)
+#else
+# define _REENT_INIT_ATEXIT \
+  _NULL, _ATEXIT_INIT,
+# define _REENT_INIT_ATEXIT_PTR(var, var0) \
+  (var)->_atexit = _NULL; _ATEXIT_INIT_PTR(var0);
 #endif
 
 /*
@@ -392,9 +415,11 @@ struct _reent
   /* signal info */
   void (**(_sig_func))(int);
 
+# ifndef _REENT_GLOBAL_ATEXIT
   /* atexit stuff */
   struct _atexit *_atexit;
   struct _atexit _atexit0;
+# endif
 
   struct _glue __sglue;			/* root of glue chain */
   __FILE *__sf;			        /* file descriptors */
@@ -425,8 +450,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
     _NULL, \
     _NULL, \
     _NULL, \
-    _NULL, \
-    {_NULL, 0, {_NULL}, _NULL}, \
+    _REENT_INIT_ATEXIT \
     {_NULL, 0, _NULL}, \
     _NULL, \
     _NULL, \
@@ -452,11 +476,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
     (var)->_localtime_buf = _NULL; \
     (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_ATEXIT_PTR(var, &(var)->_atexit0) \
     (var)->__sglue._next = _NULL; \
     (var)->__sglue._niobs = 0; \
     (var)->__sglue._iobs = _NULL; \
@@ -641,9 +661,11 @@ struct _reent
         } _unused;
     } _new;
 
+# ifndef _REENT_GLOBAL_ATEXIT
   /* atexit stuff */
   struct _atexit *_atexit;	/* points to head of LIFO stack */
   struct _atexit _atexit0;	/* one guaranteed table, required by ANSI */
+# endif
 
   /* signal info */
   void (**(_sig_func))(int);
@@ -698,8 +720,7 @@ struct _reent
         {0, {0}} \
       } \
     }, \
-    _NULL, \
-    {_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}}, \
+    _REENT_INIT_ATEXIT \
     _NULL, \
     {_NULL, 0, _NULL} \
   }
@@ -791,6 +812,13 @@ void _reclaim_reent _PARAMS ((struct _reent *));
 
 #define _GLOBAL_REENT _global_impure_ptr
 
+#ifdef _REENT_GLOBAL_ATEXIT
+extern struct _atexit *_global_atexit; /* points to head of LIFO stack */
+# define _REENT_ATEXIT(ptr) _global_atexit
+#else
+# define _REENT_ATEXIT(ptr) ((ptr)->_atexit)
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/newlib/libc/reent/reent.c b/newlib/libc/reent/reent.c
index 63812db..61da3b2 100644
--- a/newlib/libc/reent/reent.c
+++ b/newlib/libc/reent/reent.c
@@ -87,10 +87,14 @@ _DEFUN (_reclaim_reent, (ptr),
 	_free_r (ptr, ptr->_localtime_buf);
       if (ptr->_asctime_buf)
 	_free_r (ptr, ptr->_asctime_buf);
+#endif
+
+#ifndef _REENT_GLOBAL_ATEXIT
+      /* atexit stuff */
+# ifdef _REENT_SMALL
       if (ptr->_atexit && ptr->_atexit->_on_exit_args_ptr)
 	_free_r (ptr, ptr->_atexit->_on_exit_args_ptr);
-#else
-      /* atexit stuff */
+# else
       if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))
 	{
 	  struct _atexit *p, *q;
@@ -101,6 +105,7 @@ _DEFUN (_reclaim_reent, (ptr),
 	      _free_r (ptr, q);
 	    }
 	}
+# endif
 #endif
 
       if (ptr->_cvtbuf)
@@ -131,19 +136,23 @@ _DEFUN (_reclaim_reent, (ptr),
 void
 _DEFUN (_wrapup_reent, (ptr), struct _reent *ptr)
 {
+#ifndef _REENT_GLOBAL_ATEXIT
   register struct _atexit *p;
+#endif
   register int n;
 
   if (ptr == NULL)
     ptr = _REENT;
 
-#ifdef _REENT_SMALL
+#ifndef _REENT_GLOBAL_ATEXIT
+# ifdef _REENT_SMALL
   for (p = ptr->_atexit, n = p ? p->_ind : 0; --n >= 0;)
     (*p->_fns[n]) ();
-#else
+# else
   for (p = ptr->_atexit; p; p = p->_next)
     for (n = p->_ind; --n >= 0;)
       (*p->_fns[n]) ();
+# endif
 #endif
   if (ptr->__cleanup)
     (*ptr->__cleanup) (ptr);
diff --git a/newlib/libc/stdlib/__atexit.c b/newlib/libc/stdlib/__atexit.c
index 4687d00..b8104da 100644
--- a/newlib/libc/stdlib/__atexit.c
+++ b/newlib/libc/stdlib/__atexit.c
@@ -10,7 +10,17 @@
 
 /* Make this a weak reference to avoid pulling in malloc.  */
 void * malloc(size_t) _ATTRIBUTE((__weak__));
-__LOCK_INIT_RECURSIVE(, __atexit_lock);
+
+#ifndef __SINGLE_THREAD__
+extern _LOCK_RECURSIVE_T __atexit_lock;
+#endif
+
+#ifdef _REENT_GLOBAL_ATEXIT
+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.
@@ -31,9 +41,9 @@ _DEFUN (__register_exitproc,
   __lock_acquire_recursive(__atexit_lock);
 #endif
 
-  p = _GLOBAL_REENT->_atexit;
+  p = _REENT_ATEXIT(_GLOBAL_REENT);
   if (p == NULL)
-    _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
+    _REENT_ATEXIT(_GLOBAL_REENT) = p = _REENT_ATEXIT0(_GLOBAL_REENT);
   if (p->_ind >= _ATEXIT_SIZE)
     {
 #ifndef _ATEXIT_DYNAMIC_ALLOC
@@ -53,8 +63,8 @@ _DEFUN (__register_exitproc,
 	  return -1;
 	}
       p->_ind = 0;
-      p->_next = _GLOBAL_REENT->_atexit;
-      _GLOBAL_REENT->_atexit = p;
+      p->_next = _REENT_ATEXIT(_GLOBAL_REENT);
+      _REENT_ATEXIT(_GLOBAL_REENT) = p;
 #ifndef _REENT_SMALL
       p->_on_exit_args._fntypes = 0;
       p->_on_exit_args._is_cxa = 0;
diff --git a/newlib/libc/stdlib/__call_atexit.c b/newlib/libc/stdlib/__call_atexit.c
index 4c45063..b30b843 100644
--- a/newlib/libc/stdlib/__call_atexit.c
+++ b/newlib/libc/stdlib/__call_atexit.c
@@ -11,8 +11,10 @@
 /* Make this a weak reference to avoid pulling in free.  */
 void free(void *) _ATTRIBUTE((__weak__));
 
-#ifndef __SINGLE_THREAD__
-extern _LOCK_RECURSIVE_T __atexit_lock;
+__LOCK_INIT_RECURSIVE(, __atexit_lock);
+
+#ifdef _REENT_GLOBAL_ATEXIT
+struct _atexit *_global_atexit = _NULL;
 #endif
 
 #ifdef _WANT_REGISTER_FINI
@@ -78,8 +80,8 @@ _DEFUN (__call_exitprocs, (code, d),
 
  restart:
 
-  p = _GLOBAL_REENT->_atexit;
-  lastp = &_GLOBAL_REENT->_atexit;
+  p = _REENT_ATEXIT(_GLOBAL_REENT);
+  lastp = &_REENT_ATEXIT(_GLOBAL_REENT);
   while (p)
     {
 #ifdef _REENT_SMALL
-- 
1.7.10.4


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