MCPcopy Create free account
hub / github.com/OpenStarbound/OpenStarbound / _rpmalloc_aligned_allocate

Function _rpmalloc_aligned_allocate

source/extern/rpmalloc.c:2293–2409  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2291}
2292
2293static void*
2294_rpmalloc_aligned_allocate(heap_t* heap, size_t alignment, size_t size) {
2295 if (alignment <= SMALL_GRANULARITY)
2296 return _rpmalloc_allocate(heap, size);
2297
2298#if ENABLE_VALIDATE_ARGS
2299 if ((size + alignment) < size) {
2300 errno = EINVAL;
2301 return 0;
2302 }
2303 if (alignment & (alignment - 1)) {
2304 errno = EINVAL;
2305 return 0;
2306 }
2307#endif
2308
2309 if ((alignment <= SPAN_HEADER_SIZE) && ((size + SPAN_HEADER_SIZE) < _memory_medium_size_limit)) {
2310 // If alignment is less or equal to span header size (which is power of two),
2311 // and size aligned to span header size multiples is less than size + alignment,
2312 // then use natural alignment of blocks to provide alignment
2313 size_t multiple_size = size ? (size + (SPAN_HEADER_SIZE - 1)) & ~(uintptr_t)(SPAN_HEADER_SIZE - 1) : SPAN_HEADER_SIZE;
2314 rpmalloc_assert(!(multiple_size % SPAN_HEADER_SIZE), "Failed alignment calculation");
2315 if (multiple_size <= (size + alignment))
2316 return _rpmalloc_allocate(heap, multiple_size);
2317 }
2318
2319 void* ptr = 0;
2320 size_t align_mask = alignment - 1;
2321 if (alignment <= _memory_page_size) {
2322 ptr = _rpmalloc_allocate(heap, size + alignment);
2323 if ((uintptr_t)ptr & align_mask) {
2324 ptr = (void*)(((uintptr_t)ptr & ~(uintptr_t)align_mask) + alignment);
2325 //Mark as having aligned blocks
2326 span_t* span = (span_t*)((uintptr_t)ptr & _memory_span_mask);
2327 span->flags |= SPAN_FLAG_ALIGNED_BLOCKS;
2328 }
2329 return ptr;
2330 }
2331
2332 // Fallback to mapping new pages for this request. Since pointers passed
2333 // to rpfree must be able to reach the start of the span by bitmasking of
2334 // the address with the span size, the returned aligned pointer from this
2335 // function must be with a span size of the start of the mapped area.
2336 // In worst case this requires us to loop and map pages until we get a
2337 // suitable memory address. It also means we can never align to span size
2338 // or greater, since the span header will push alignment more than one
2339 // span size away from span start (thus causing pointer mask to give us
2340 // an invalid span start on free)
2341 if (alignment & align_mask) {
2342 errno = EINVAL;
2343 return 0;
2344 }
2345 if (alignment >= _memory_span_size) {
2346 errno = EINVAL;
2347 return 0;
2348 }
2349
2350 size_t extra_pages = alignment / _memory_page_size;

Callers 4

rpaligned_allocFunction · 0.85

Calls 4

_rpmalloc_allocateFunction · 0.85
_rpmalloc_mmapFunction · 0.85
_rpmalloc_unmapFunction · 0.85

Tested by

no test coverage detected