OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.18.0/] [newlib/] [libc/] [stdlib/] [__call_atexit.c] - Blame information for rev 258

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/*
2
 * COmmon routine to call call registered atexit-like routines.
3
 */
4
 
5
 
6
#include <stdlib.h>
7
#include <reent.h>
8
#include "atexit.h"
9
 
10
/* Make this a weak reference to avoid pulling in free.  */
11
void free(void *) _ATTRIBUTE((__weak__));
12
 
13
/*
14
 * Call registered exit handlers.  If D is null then all handlers are called,
15
 * otherwise only the handlers from that DSO are called.
16
 */
17
 
18
void
19
_DEFUN (__call_exitprocs, (code, d),
20
        int code _AND _PTR d)
21
{
22
  register struct _atexit *p;
23
  struct _atexit **lastp;
24
  register struct _on_exit_args * args;
25
  register int n;
26
  int i;
27
  void (*fn) (void);
28
 
29
 restart:
30
 
31
  p = _GLOBAL_REENT->_atexit;
32
  lastp = &_GLOBAL_REENT->_atexit;
33
  while (p)
34
    {
35
#ifdef _REENT_SMALL
36
      args = p->_on_exit_args_ptr;
37
#else
38
      args = &p->_on_exit_args;
39
#endif
40
      for (n = p->_ind - 1; n >= 0; n--)
41
        {
42
          int ind;
43
 
44
          i = 1 << n;
45
 
46
          /* Skip functions not from this dso.  */
47
          if (d && (!args || args->_dso_handle[n] != d))
48
            continue;
49
 
50
          /* Remove the function now to protect against the
51
             function calling exit recursively.  */
52
          fn = p->_fns[n];
53
          if (n == p->_ind - 1)
54
            p->_ind--;
55
          else
56
            p->_fns[n] = NULL;
57
 
58
          /* Skip functions that have already been called.  */
59
          if (!fn)
60
            continue;
61
 
62
          ind = p->_ind;
63
 
64
          /* Call the function.  */
65
          if (!args || (args->_fntypes & i) == 0)
66
            fn ();
67
          else if ((args->_is_cxa & i) == 0)
68
            (*((void (*)(int, _PTR)) fn))(code, args->_fnargs[n]);
69
          else
70
            (*((void (*)(_PTR)) fn))(args->_fnargs[n]);
71
 
72
          /* The function we called call atexit and registered another
73
             function (or functions).  Call these new functions before
74
             continuing with the already registered functions.  */
75
          if (ind != p->_ind || *lastp != p)
76
            goto restart;
77
        }
78
 
79
#ifndef _ATEXIT_DYNAMIC_ALLOC
80
      break;
81
#else
82
      /* Don't dynamically free the atexit array if free is not
83
         available.  */
84
      if (!free)
85
        break;
86
 
87
      /* Move to the next block.  Free empty blocks except the last one,
88
         which is part of _GLOBAL_REENT.  */
89
      if (p->_ind == 0 && p->_next)
90
        {
91
          /* Remove empty block from the list.  */
92
          *lastp = p->_next;
93
#ifdef _REENT_SMALL
94
          if (args)
95
            free (args);
96
#endif
97
          free (p);
98
          p = *lastp;
99
        }
100
      else
101
        {
102
          lastp = &p->_next;
103
          p = p->_next;
104
        }
105
#endif
106
    }
107
}

powered by: WebSVN 2.1.0

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