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