| 39 | } |
| 40 | |
| 41 | U32 BHeap::alloc(KMemory* memory, KThread* thread, U32 len) { |
| 42 | U32 index = powerOf2(len + 4); |
| 43 | if (index < BHEAP_MIN_BUCKET) { |
| 44 | index = BHEAP_MIN_BUCKET; |
| 45 | } |
| 46 | if (index >= BHEAP_MIN_BUCKET + BHEAP_NUMBER_OF_BUCKETS) { |
| 47 | len += 4; |
| 48 | len = (len + K_PAGE_MASK) & ~K_PAGE_MASK; |
| 49 | U32 address = memory->mmap(thread, 0, len, K_PROT_READ | K_PROT_WRITE, K_MAP_ANONYMOUS | K_MAP_PRIVATE | K_MAP_BOXEDWINE, -1, 0); |
| 50 | memory->writed(address, len); |
| 51 | return address + 4; |
| 52 | } |
| 53 | index = index - BHEAP_MIN_BUCKET; |
| 54 | if (bucket[index].size() > 0) { |
| 55 | U32 result = bucket[index].back(); |
| 56 | bucket[index].pop_back(); |
| 57 | return result; |
| 58 | } |
| 59 | U32 address = memory->mmap(thread, 0, K_PAGE_SIZE, K_PROT_READ | K_PROT_WRITE, K_MAP_ANONYMOUS | K_MAP_PRIVATE | K_MAP_BOXEDWINE, -1, 0); |
| 60 | U32 size = 1 << (index + BHEAP_MIN_BUCKET); |
| 61 | |
| 62 | pages.push_back(address); |
| 63 | for (U32 start = address; start < address + K_PAGE_SIZE; start += size) { |
| 64 | memory->writed(start, index); |
| 65 | bucket[index].push_back(start + 4); |
| 66 | } |
| 67 | return alloc(memory, thread, len); |
| 68 | } |
| 69 | |
| 70 | void BHeap::free(KMemory* memory, U32 address) { |
| 71 | if (!address) { |
no test coverage detected