1#ifndef HALIDE_RUNTIME_MEMORY_ARENA_H
2#define HALIDE_RUNTIME_MEMORY_ARENA_H
69 void *entries =
nullptr;
93 blocks(
user_context, {
sizeof(MemoryArena::Block), 32, 32}, alloc) {
106 if (result ==
nullptr) {
132 if (!blocks.
empty()) {
133 for (
size_t i = blocks.
size(); i--;) {
144 for (
size_t i = blocks.
size(); i--;) {
157 for (
size_t i = blocks.
size(); i--;) {
160 if (block->free_index != invalid_entry) {
161 return create_entry(
user_context, block, block->free_index);
173 void *entry_ptr = create_entry(
user_context, block, index);
183 for (
size_t i = blocks.
size(); i--;) {
191 if ((entry_ptr >= base_ptr) && (entry_ptr < end_ptr)) {
201typename MemoryArena::Block *MemoryArena::create_block(
void *
user_context) {
204 if (!blocks.
empty()) {
205 const Block *last_block =
static_cast<Block *
>(blocks.
back());
206 new_capacity = (last_block->capacity * 3 / 2);
216 for (
uint32_t i = 0; i < new_capacity - 1; ++i) {
217 new_indices[i] = i + 1;
221 new_indices[new_capacity - 1] = invalid_entry;
224 const Block new_block = {new_entries, new_indices, new_status, new_capacity, 0};
226 return static_cast<Block *
>(blocks.
back());
229void MemoryArena::destroy_block(
void *
user_context, Block *block) {
231 if (block->entries !=
nullptr) {
236 block->entries =
nullptr;
237 block->indices =
nullptr;
238 block->status =
nullptr;
242bool MemoryArena::collect_block(
void *
user_context, Block *block) {
244 if (block->entries !=
nullptr) {
245 bool can_collect =
true;
246 for (
size_t i = block->capacity; i--;) {
261 return static_cast<Block *
>(blocks[index]);
271 void *entry_ptr = lookup_entry(
user_context, block, index);
272 block->free_index = block->indices[index];
274#ifdef DEBUG_RUNTIME_INTERNAL
282 block->indices[index] = block->free_index;
283 block->free_index = index;
286const typename MemoryArena::Config &
This file declares the routines used by Halide internally in its runtime.
void halide_error(void *user_context, const char *)
Halide calls this function on runtime errors (for example bounds checking failures).
void destroy(void *user_context)
void remove(void *user_context, size_t index)
void initialize(void *user_context, const Config &cfg, const SystemMemoryAllocatorFns &sma=default_allocator())
static const SystemMemoryAllocatorFns & default_allocator()
const SystemMemoryAllocatorFns & current_allocator() const
void append(void *user_context, const void *entry_ptr)
void initialize(void *user_context, const Config &config, const SystemMemoryAllocatorFns &allocator=default_allocator())
void * reserve(void *user_context, bool initialize=false)
static MemoryArena * create(void *user_context, const Config &config, const SystemMemoryAllocatorFns &allocator=default_allocator())
const Config & current_config() const
static constexpr uint32_t default_capacity
const SystemMemoryAllocatorFns & current_allocator() const
static const Config & default_config()
static void destroy(void *user_context, MemoryArena *arena)
MemoryArena(const MemoryArena &)=delete
void reclaim(void *user_context, void *ptr)
bool collect(void *user_context)
MemoryArena & operator=(const MemoryArena &)=delete
static const SystemMemoryAllocatorFns & default_allocator()
ALWAYS_INLINE const void * offset_address(const void *address, size_t byte_offset)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
#define halide_debug_assert(user_context, cond)
halide_debug_assert() is like halide_assert(), but only expands into a check when DEBUG_RUNTIME is de...
unsigned __INT8_TYPE__ uint8_t
void * memset(void *s, int val, size_t n)
unsigned __INT32_TYPE__ uint32_t
uint32_t maximum_block_count
uint32_t minimum_block_capacity
DeallocateSystemFn deallocate
AllocateSystemFn allocate
VulkanMemoryAllocator * allocator