blob: 40320dc7e48313c47ffdb31242a207bda43f6468 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#include <libc.h>
#include <sys/mman.h>
#include <atomic.h>
#include <malloc.h>
#include <stdint.h>
#include <stdbool.h>
void free(void *ptr)
{
if (ptr == NULL) {
return;
}
LIBC_LOCK(libc.lock.malloc);
struct page *p = __malloc_pvec;
int found_in_pages = 0;
while (p) {
if ((uintptr_t)ptr >= (uintptr_t)p->heap &&
(uintptr_t)ptr < (uintptr_t)(p->heap + (p->block.size *
p->block.count))) {
size_t offset = (uintptr_t)ptr - (uintptr_t)p->heap;
size_t index = offset / p->block.size;
size_t byte_index = index / 8;
size_t bit_index = index % 8;
LIBC_LOCK(p->lock);
if (p->bitmap[byte_index] & (1 << bit_index)) {
p->bitmap[byte_index] &= ~(1 << bit_index);
p->block.used--;
found_in_pages = 1;
}
LIBC_UNLOCK(p->lock);
if (found_in_pages && p->block.used == 0) {
if (p->prev)
p->prev->next = p->next;
if (p->next)
p->next->prev = p->prev;
if (p == __malloc_pvec)
__malloc_pvec = p->next;
munmap(p, (p->flags == PAGE_SMALL) ?
SMALL_PAGE_SIZE :
(p->flags == PAGE_MEDIUM) ?
MEDIUM_PAGE_SIZE :
LARGE_PAGE_SIZE);
}
LIBC_UNLOCK(libc.lock.malloc);
return;
}
p = p->next;
}
void **orig_ptr_slot = (void **)((uintptr_t)ptr - sizeof(void *));
void *potential_orig = *orig_ptr_slot;
p = __malloc_pvec;
while (p) {
if ((uintptr_t)potential_orig >= (uintptr_t)p->heap &&
(uintptr_t)potential_orig <
(uintptr_t)(p->heap +
(p->block.size * p->block.count))) {
size_t offset =
(uintptr_t)potential_orig - (uintptr_t)p->heap;
size_t index = offset / p->block.size;
size_t byte_index = index / 8;
size_t bit_index = index % 8;
LIBC_LOCK(p->lock);
if (p->bitmap[byte_index] & (1 << bit_index)) {
p->bitmap[byte_index] &= ~(1 << bit_index);
p->block.used--;
}
LIBC_UNLOCK(p->lock);
if (p->block.used == 0) {
if (p->prev)
p->prev->next = p->next;
if (p->next)
p->next->prev = p->prev;
if (p == __malloc_pvec)
__malloc_pvec = p->next;
munmap(p, (p->flags == PAGE_SMALL) ?
SMALL_PAGE_SIZE :
(p->flags == PAGE_MEDIUM) ?
MEDIUM_PAGE_SIZE :
LARGE_PAGE_SIZE);
}
LIBC_UNLOCK(libc.lock.malloc);
return;
}
p = p->next;
}
LIBC_UNLOCK(libc.lock.malloc);
}
|