X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fexit%2Fatexit.c;h=854e9fddbe559218805261c7623dbaa7304569d1;hb=233bb6972d84e9cb908ff038f78d97e487082225;hp=9d9c2fbe6d9cac066c481cb267110de4d779fabe;hpb=14f2e115c2a1ee473ec8f28b1e804329f6a4d765;p=musl diff --git a/src/exit/atexit.c b/src/exit/atexit.c index 9d9c2fbe..854e9fdd 100644 --- a/src/exit/atexit.c +++ b/src/exit/atexit.c @@ -1,8 +1,13 @@ -#include #include #include -#include #include "libc.h" +#include "lock.h" +#include "fork_impl.h" + +#define malloc __libc_malloc +#define calloc __libc_calloc +#define realloc undef +#define free undef /* Ensure that at least 32 atexit handlers can be registered without malloc */ #define COUNT 32 @@ -14,22 +19,20 @@ static struct fl void *a[COUNT]; } builtin, *head; -static int lock; +static int slot; +static volatile int lock[1]; +volatile int *const __atexit_lockptr = lock; void __funcs_on_exit() { - int i; void (*func)(void *), *arg; - LOCK(&lock); - for (; head; head=head->next) { - for (i=COUNT-1; i>=0 && !head->f[i]; i--); - if (i<0) continue; - func = head->f[i]; - arg = head->a[i]; - head->f[i] = 0; - UNLOCK(&lock); + 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); + LOCK(lock); } } @@ -39,30 +42,29 @@ void __cxa_finalize(void *dso) int __cxa_atexit(void (*func)(void *), void *arg, void *dso) { - int i; - - LOCK(&lock); + 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 (head->f[COUNT-1]) { + if (slot==COUNT) { struct fl *new_fl = calloc(sizeof(struct fl), 1); if (!new_fl) { - UNLOCK(&lock); + UNLOCK(lock); return -1; } new_fl->next = head; head = new_fl; + slot = 0; } /* Append function to the list. */ - for (i=0; if[i]; i++); - head->f[i] = func; - head->a[i] = arg; + head->f[slot] = func; + head->a[slot] = arg; + slot++; - UNLOCK(&lock); + UNLOCK(lock); return 0; }