µOS++ IIIe Reference  v6.3.15
“Perfekt ist nicht gut genug”
The third edition of µOS++, a POSIX inspired open source system, written in C++.
atexit.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the µOS++ distribution.
3  * (https://github.com/micro-os-plus)
4  * Copyright (c) 2015 Liviu Ionescu.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom
12  * the Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #if defined(__ARM_EABI__)
29 
30 // ----------------------------------------------------------------------------
31 
32 #include <cmsis-plus/rtos/os.h>
33 #include <cmsis-plus/diag/trace.h>
34 
35 #include <stdlib.h>
36 #include <assert.h>
37 
38 #include "atexit.h"
39 
40 // ----------------------------------------------------------------------------
41 
42 #if defined(OS_INCLUDE_ATEXIT_STATIC) && !defined(__EXCEPTIONS)
43 
72 int
73 atexit (exit_func_t fn)
74 {
75 #if defined(OS_TRACE_LIBC_ATEXIT)
76  trace_printf ("%s(%p)\n", __func__, fn);
77 #endif
78 
79  return __register_exitproc (__et_atexit, fn, NULL, NULL);
80 }
81 
82 // ----------------------------------------------------------------------------
83 
84 #if !defined(OS_INTEGER_ATEXIT_ARRAY_SIZE)
85 // Due to an odd behaviour, destructors for main and idle are
86 // called via atexit().
87 #define OS_INTEGER_ATEXIT_ARRAY_SIZE (3)
88 #endif
89 
93 size_t __atexit_count;
94 
102 exit_func_t __atexit_functions[OS_INTEGER_ATEXIT_ARRAY_SIZE];
103 
117 int
118 __register_exitproc (int type, exit_func_t fn,
119  void *arg __attribute__((unused)),
120  void *d __attribute__((unused)))
121 {
122  assert(type == __et_atexit);
123  assert(__atexit_count < OS_INTEGER_ATEXIT_ARRAY_SIZE);
124 
125 #if defined(NDEBUG)
126  if ((type != __et_atexit) || (__atexit_count >= OS_INTEGER_ATEXIT_ARRAY_SIZE))
127  {
128  return -1;
129  }
130 #endif
131 
132  // Use scheduler lock to synchronise access to the array.
134 
135  __atexit_functions[__atexit_count++] = fn;
136  return 0;
137 }
138 
139 // ----------------------------------------------------------------------------
140 
141 void
142 __call_exitprocs (int code __attribute__((unused)),
143  void* d __attribute__((unused)))
144 {
145  trace_printf("%s()\n", __func__);
146 
147  // Call registered functions in reverse order.
148  for (size_t i = __atexit_count; i > 0;)
149  {
150  __atexit_functions[--i] ();
151  }
152 }
153 
154 #endif /* !defined(__EXCEPTIONS) */
155 
156 // ----------------------------------------------------------------------------
157 
158 #endif /* defined(__ARM_EABI__) */
#define OS_INTEGER_ATEXIT_ARRAY_SIZE
Define the size of the atexit() array.
void(* exit_func_t)(void)
Definition: atexit.h:56
int __register_exitproc(int, exit_func_t fn, void *, void *)
Scheduler critical section RAII helper.
Definition: os-sched.h:170
void __call_exitprocs(int, void *)
Single file µOS++ RTOS definitions.
int trace_printf(const char *format,...)