123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- #include <stdlib.h>
- #include <stdint.h>
- #include "libc.h"
- #include "lock.h"
- /* Ensure that at least 32 atexit handlers can be registered without malloc */
- #define COUNT 32
- static struct fl
- {
- struct fl *next;
- void (*f[COUNT])(void *);
- void *a[COUNT];
- } builtin, *head;
- static int slot;
- static volatile int lock[1];
- void __funcs_on_exit()
- {
- void (*func)(void *), *arg;
- LOCK(lock);
- for (; head; head=head->next, slot=COUNT) while(slot-->0) {
- func = head->f[slot];
- arg = head->a[slot];
- UNLOCK(lock);
- func(arg);
- LOCK(lock);
- }
- }
- void __cxa_finalize(void *dso)
- {
- }
- int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
- {
- LOCK(lock);
- /* Defer initialization of head so it can be in BSS */
- if (!head) head = &builtin;
- /* If the current function list is full, add a new one */
- if (slot==COUNT) {
- struct fl *new_fl = calloc(sizeof(struct fl), 1);
- if (!new_fl) {
- UNLOCK(lock);
- return -1;
- }
- new_fl->next = head;
- head = new_fl;
- slot = 0;
- }
- /* Append function to the list. */
- head->f[slot] = func;
- head->a[slot] = arg;
- slot++;
- UNLOCK(lock);
- return 0;
- }
- static void call(void *p)
- {
- ((void (*)(void))(uintptr_t)p)();
- }
- int atexit(void (*func)(void))
- {
- return __cxa_atexit(call, (void *)(uintptr_t)func, 0);
- }
|