/* rpquery Returns extended block information from block base pointer Params: _block : pointer to base of an allocated block _out : block info that will be initialized by the function Returns: _out */ RP_PUBLIC_INFO* rpquery(void* _block, RP_PUBLIC_INFO* _out) { RP_BLOCK_HEADER* rbhBlock = get_block_header(_block); _out->cbBlock = rbhBlock->cbBlock; _out->cbRealSize = (size_t)((uintptr_t)rbhBlock->pNext - (uintptr_t)_block); return _out; }
void* rpreallocEx(rpheap_t _heap, void* _old_ptr, size_t _new_cb) { RP_BLOCK_HEADER* rbhBlock = get_block_header(_old_ptr); // special case if block is already large enough if (rbhBlock->cbBlock >= _new_cb) return _old_ptr; // TODO: Check if current block can be expanded void* pNew = rpmallocEx(_heap, _new_cb); rpmemcpy(pNew, _old_ptr, rbhBlock->cbBlock); rpfree(_old_ptr); return pNew; }
void* internal_realloc(void *ptr, size_t size) { if (ptr == NULL) return internal_alloc(size, DEFAULT_ALIGNMENT); if (size == 0) return nullptr; void* new_data = NULL; auto head = get_block_header(ptr); if (size>0) new_data = internal_alloc(size, head->alignment); if (!new_data) return nullptr; mcpy(new_data, ptr, min(size, head->total_size - sizeof(block_header) - head->alignment + 1)); internal_free(ptr); return new_data; }
void rpfreeEx(rpheap_t _heap, void* _block) { if (_heap == NULL) _heap = default_heap; RP_HEAP_HEADER* rhh = _heap; RP_BLOCK_HEADER *rbhBlock = get_block_header(_block), *rbhPrev = rhh->pBase; *rbhNext = rbhBlock->pNext; // set rbhPrev to block before rbhBlock while (rbhPrev->pNext != rbhBlock && rbhPrev->pNext != NULL) rbhPrev = rbhPrev->pNext; // if it's null then we have reached the end of the list and were passed an invalid block assert(rbhPrev->pNext); // pretend it never happened and unlink rbhPrev->pNext = rbhBlockNext; // update heap header rhh->cbFree += rbhBlock->cbBlock; }