xref: /aosp_15_r20/external/musl/src/exit/atexit.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include <stdlib.h>
2*c9945492SAndroid Build Coastguard Worker #include <stdint.h>
3*c9945492SAndroid Build Coastguard Worker #include "libc.h"
4*c9945492SAndroid Build Coastguard Worker #include "lock.h"
5*c9945492SAndroid Build Coastguard Worker #include "fork_impl.h"
6*c9945492SAndroid Build Coastguard Worker 
7*c9945492SAndroid Build Coastguard Worker #define malloc __libc_malloc
8*c9945492SAndroid Build Coastguard Worker #define calloc __libc_calloc
9*c9945492SAndroid Build Coastguard Worker #define realloc undef
10*c9945492SAndroid Build Coastguard Worker #define free undef
11*c9945492SAndroid Build Coastguard Worker 
12*c9945492SAndroid Build Coastguard Worker /* Ensure that at least 32 atexit handlers can be registered without malloc */
13*c9945492SAndroid Build Coastguard Worker #define COUNT 32
14*c9945492SAndroid Build Coastguard Worker 
15*c9945492SAndroid Build Coastguard Worker static struct fl
16*c9945492SAndroid Build Coastguard Worker {
17*c9945492SAndroid Build Coastguard Worker 	struct fl *next;
18*c9945492SAndroid Build Coastguard Worker 	void (*f[COUNT])(void *);
19*c9945492SAndroid Build Coastguard Worker 	void *a[COUNT];
20*c9945492SAndroid Build Coastguard Worker } builtin, *head;
21*c9945492SAndroid Build Coastguard Worker 
22*c9945492SAndroid Build Coastguard Worker static int slot;
23*c9945492SAndroid Build Coastguard Worker static volatile int lock[1];
24*c9945492SAndroid Build Coastguard Worker volatile int *const __atexit_lockptr = lock;
25*c9945492SAndroid Build Coastguard Worker 
__funcs_on_exit()26*c9945492SAndroid Build Coastguard Worker void __funcs_on_exit()
27*c9945492SAndroid Build Coastguard Worker {
28*c9945492SAndroid Build Coastguard Worker 	void (*func)(void *), *arg;
29*c9945492SAndroid Build Coastguard Worker 	LOCK(lock);
30*c9945492SAndroid Build Coastguard Worker 	for (; head; head=head->next, slot=COUNT) while(slot-->0) {
31*c9945492SAndroid Build Coastguard Worker 		func = head->f[slot];
32*c9945492SAndroid Build Coastguard Worker 		arg = head->a[slot];
33*c9945492SAndroid Build Coastguard Worker 		UNLOCK(lock);
34*c9945492SAndroid Build Coastguard Worker 		func(arg);
35*c9945492SAndroid Build Coastguard Worker 		LOCK(lock);
36*c9945492SAndroid Build Coastguard Worker 	}
37*c9945492SAndroid Build Coastguard Worker }
38*c9945492SAndroid Build Coastguard Worker 
__cxa_finalize(void * dso)39*c9945492SAndroid Build Coastguard Worker void __cxa_finalize(void *dso)
40*c9945492SAndroid Build Coastguard Worker {
41*c9945492SAndroid Build Coastguard Worker }
42*c9945492SAndroid Build Coastguard Worker 
__cxa_atexit(void (* func)(void *),void * arg,void * dso)43*c9945492SAndroid Build Coastguard Worker int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
44*c9945492SAndroid Build Coastguard Worker {
45*c9945492SAndroid Build Coastguard Worker 	LOCK(lock);
46*c9945492SAndroid Build Coastguard Worker 
47*c9945492SAndroid Build Coastguard Worker 	/* Defer initialization of head so it can be in BSS */
48*c9945492SAndroid Build Coastguard Worker 	if (!head) head = &builtin;
49*c9945492SAndroid Build Coastguard Worker 
50*c9945492SAndroid Build Coastguard Worker 	/* If the current function list is full, add a new one */
51*c9945492SAndroid Build Coastguard Worker 	if (slot==COUNT) {
52*c9945492SAndroid Build Coastguard Worker 		struct fl *new_fl = calloc(sizeof(struct fl), 1);
53*c9945492SAndroid Build Coastguard Worker 		if (!new_fl) {
54*c9945492SAndroid Build Coastguard Worker 			UNLOCK(lock);
55*c9945492SAndroid Build Coastguard Worker 			return -1;
56*c9945492SAndroid Build Coastguard Worker 		}
57*c9945492SAndroid Build Coastguard Worker 		new_fl->next = head;
58*c9945492SAndroid Build Coastguard Worker 		head = new_fl;
59*c9945492SAndroid Build Coastguard Worker 		slot = 0;
60*c9945492SAndroid Build Coastguard Worker 	}
61*c9945492SAndroid Build Coastguard Worker 
62*c9945492SAndroid Build Coastguard Worker 	/* Append function to the list. */
63*c9945492SAndroid Build Coastguard Worker 	head->f[slot] = func;
64*c9945492SAndroid Build Coastguard Worker 	head->a[slot] = arg;
65*c9945492SAndroid Build Coastguard Worker 	slot++;
66*c9945492SAndroid Build Coastguard Worker 
67*c9945492SAndroid Build Coastguard Worker 	UNLOCK(lock);
68*c9945492SAndroid Build Coastguard Worker 	return 0;
69*c9945492SAndroid Build Coastguard Worker }
70*c9945492SAndroid Build Coastguard Worker 
call(void * p)71*c9945492SAndroid Build Coastguard Worker static void call(void *p)
72*c9945492SAndroid Build Coastguard Worker {
73*c9945492SAndroid Build Coastguard Worker 	((void (*)(void))(uintptr_t)p)();
74*c9945492SAndroid Build Coastguard Worker }
75*c9945492SAndroid Build Coastguard Worker 
atexit(void (* func)(void))76*c9945492SAndroid Build Coastguard Worker int atexit(void (*func)(void))
77*c9945492SAndroid Build Coastguard Worker {
78*c9945492SAndroid Build Coastguard Worker 	return __cxa_atexit(call, (void *)(uintptr_t)func, 0);
79*c9945492SAndroid Build Coastguard Worker }
80