OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc1/] [newlib/] [libc/] [stdlib/] [__call_atexit.c] - Diff between revs 207 and 345

Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 345
/*
/*
 * COmmon routine to call call registered atexit-like routines.
 * COmmon routine to call call registered atexit-like routines.
 */
 */
 
 
 
 
#include <stdlib.h>
#include <stdlib.h>
#include <reent.h>
#include <reent.h>
#include "atexit.h"
#include "atexit.h"
 
 
/* Make this a weak reference to avoid pulling in free.  */
/* Make this a weak reference to avoid pulling in free.  */
void free(void *) _ATTRIBUTE((__weak__));
void free(void *) _ATTRIBUTE((__weak__));
 
 
/*
/*
 * Call registered exit handlers.  If D is null then all handlers are called,
 * Call registered exit handlers.  If D is null then all handlers are called,
 * otherwise only the handlers from that DSO are called.
 * otherwise only the handlers from that DSO are called.
 */
 */
 
 
void
void
_DEFUN (__call_exitprocs, (code, d),
_DEFUN (__call_exitprocs, (code, d),
        int code _AND _PTR d)
        int code _AND _PTR d)
{
{
  register struct _atexit *p;
  register struct _atexit *p;
  struct _atexit **lastp;
  struct _atexit **lastp;
  register struct _on_exit_args * args;
  register struct _on_exit_args * args;
  register int n;
  register int n;
  int i;
  int i;
  void (*fn) (void);
  void (*fn) (void);
 
 
 restart:
 restart:
 
 
  p = _GLOBAL_REENT->_atexit;
  p = _GLOBAL_REENT->_atexit;
  lastp = &_GLOBAL_REENT->_atexit;
  lastp = &_GLOBAL_REENT->_atexit;
  while (p)
  while (p)
    {
    {
#ifdef _REENT_SMALL
#ifdef _REENT_SMALL
      args = p->_on_exit_args_ptr;
      args = p->_on_exit_args_ptr;
#else
#else
      args = &p->_on_exit_args;
      args = &p->_on_exit_args;
#endif
#endif
      for (n = p->_ind - 1; n >= 0; n--)
      for (n = p->_ind - 1; n >= 0; n--)
        {
        {
          int ind;
          int ind;
 
 
          i = 1 << n;
          i = 1 << n;
 
 
          /* Skip functions not from this dso.  */
          /* Skip functions not from this dso.  */
          if (d && (!args || args->_dso_handle[n] != d))
          if (d && (!args || args->_dso_handle[n] != d))
            continue;
            continue;
 
 
          /* Remove the function now to protect against the
          /* Remove the function now to protect against the
             function calling exit recursively.  */
             function calling exit recursively.  */
          fn = p->_fns[n];
          fn = p->_fns[n];
          if (n == p->_ind - 1)
          if (n == p->_ind - 1)
            p->_ind--;
            p->_ind--;
          else
          else
            p->_fns[n] = NULL;
            p->_fns[n] = NULL;
 
 
          /* Skip functions that have already been called.  */
          /* Skip functions that have already been called.  */
          if (!fn)
          if (!fn)
            continue;
            continue;
 
 
          ind = p->_ind;
          ind = p->_ind;
 
 
          /* Call the function.  */
          /* Call the function.  */
          if (!args || (args->_fntypes & i) == 0)
          if (!args || (args->_fntypes & i) == 0)
            fn ();
            fn ();
          else if ((args->_is_cxa & i) == 0)
          else if ((args->_is_cxa & i) == 0)
            (*((void (*)(int, _PTR)) fn))(code, args->_fnargs[n]);
            (*((void (*)(int, _PTR)) fn))(code, args->_fnargs[n]);
          else
          else
            (*((void (*)(_PTR)) fn))(args->_fnargs[n]);
            (*((void (*)(_PTR)) fn))(args->_fnargs[n]);
 
 
          /* The function we called call atexit and registered another
          /* The function we called call atexit and registered another
             function (or functions).  Call these new functions before
             function (or functions).  Call these new functions before
             continuing with the already registered functions.  */
             continuing with the already registered functions.  */
          if (ind != p->_ind || *lastp != p)
          if (ind != p->_ind || *lastp != p)
            goto restart;
            goto restart;
        }
        }
 
 
#ifndef _ATEXIT_DYNAMIC_ALLOC
#ifndef _ATEXIT_DYNAMIC_ALLOC
      break;
      break;
#else
#else
      /* Don't dynamically free the atexit array if free is not
      /* Don't dynamically free the atexit array if free is not
         available.  */
         available.  */
      if (!free)
      if (!free)
        break;
        break;
 
 
      /* Move to the next block.  Free empty blocks except the last one,
      /* Move to the next block.  Free empty blocks except the last one,
         which is part of _GLOBAL_REENT.  */
         which is part of _GLOBAL_REENT.  */
      if (p->_ind == 0 && p->_next)
      if (p->_ind == 0 && p->_next)
        {
        {
          /* Remove empty block from the list.  */
          /* Remove empty block from the list.  */
          *lastp = p->_next;
          *lastp = p->_next;
#ifdef _REENT_SMALL
#ifdef _REENT_SMALL
          if (args)
          if (args)
            free (args);
            free (args);
#endif
#endif
          free (p);
          free (p);
          p = *lastp;
          p = *lastp;
        }
        }
      else
      else
        {
        {
          lastp = &p->_next;
          lastp = &p->_next;
          p = p->_next;
          p = p->_next;
        }
        }
#endif
#endif
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.