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