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]

Re: [PATCH] Add and use _REENT_GLOBAL_ATEXIT


I would like to change this.

I don't like having a macro that takes a ptr argument and ignores it. I also would prefer consistency with the impure ptr struct declarations. The atexit0 storage is supposed to be statically guaranteed which is currently accomplished by being part of the static global reent struct.

My preference is that you declare a static atexit0_data struct inside impure.c along-side the impure_data declaration (being controlled by your new _REENT_GLOBAL_ATEXIT macro).

Then, you have two macros:

_GLOBAL_ATEXIT (which is either _GLOBAL_REENT->_atexit or _impure_atexit (whatever you call it), which is also declared in impure.c based on the _REENT_GLOBAL_ATEXIT macro.

and

_GLOBAL_ATEXIT0 (which is either &(_GLOBAL_REENT->_atexit0) or the address of _impure_atexit0_data or whatever you put in impure.c for atexit0).

It becomes relatively straightforward after that to change the existing code.

I probably would not have bothered moving the _atexit pointer out of the struct myself since it is such a minor gain compared to the atexit0 savings but whatever.

-- Jeff J.



On 05/01/2013 11:58 AM, Sebastian Huber wrote:
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



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