| 244 | } |
| 245 | |
| 246 | vaddr_t vmem_alloc(size_t size) { |
| 247 | lock_allocator(); |
| 248 | size_t alloc_size = size + offsetof(Block, data); |
| 249 | int level = find_level(alloc_size); |
| 250 | int flevel = level; |
| 251 | while (flevel < LOG2_SEGMENT_SIZE && vmem.freelist[flevel] == VADDR_NULL) |
| 252 | flevel++; |
| 253 | if (vmem.freelist[flevel] == VADDR_NULL) { |
| 254 | vmem.add_segment(); |
| 255 | } |
| 256 | vmem.ensure_is_mapped(vmem.freelist[flevel]); |
| 257 | while (flevel > level) { |
| 258 | // get and split a block |
| 259 | vaddr_t blockaddr = vmem.freelist[flevel]; |
| 260 | assert((blockaddr & ((1 << flevel) - 1)) == 0); |
| 261 | Block *block = vmem.block_ptr(blockaddr); |
| 262 | vmem.freelist[flevel] = block->next; |
| 263 | if (vmem.freelist[flevel] != VADDR_NULL) |
| 264 | vmem.block_ptr(vmem.freelist[flevel])->prev = VADDR_NULL; |
| 265 | vaddr_t blockaddr2 = blockaddr + (1 << (flevel - 1)); |
| 266 | Block *block2 = vmem.block_ptr(blockaddr2); |
| 267 | flevel--; |
| 268 | block2->next = vmem.freelist[flevel]; |
| 269 | block2->prev = blockaddr; |
| 270 | block->next = blockaddr2; |
| 271 | block->prev = VADDR_NULL; |
| 272 | // block->prev == VADDR_NULL already. |
| 273 | vmem.freelist[flevel] = blockaddr; |
| 274 | } |
| 275 | assert(vmem.freelist[level] != VADDR_NULL); |
| 276 | Block *block = vmem.block_ptr(vmem.freelist[level]); |
| 277 | vaddr_t vaddr = vmem.freelist[level]; |
| 278 | #if defined(__GNUC__) && (__GNUC__>11) |
| 279 | vaddr_t result = vaddr + (sizeof(vaddr_t)*2); |
| 280 | #else |
| 281 | vaddr_t result = vaddr + offsetof(Block, data); |
| 282 | #endif |
| 283 | vmem.freelist[level] = block->next; |
| 284 | if (block->next != VADDR_NULL) |
| 285 | vmem.block_ptr(block->next)->prev = VADDR_NULL; |
| 286 | block->mark_as_allocated(vaddr, level); |
| 287 | unlock_allocator(); |
| 288 | memset(block->data, 0, size); |
| 289 | return result; |
| 290 | } |
| 291 | |
| 292 | void init_flock_struct( |
| 293 | struct flock &lock_info, size_t offset, size_t len, bool lock) { |
no test coverage detected