1#ifndef HALIDE_RUNTIME_BLOCK_STORAGE_H
2#define HALIDE_RUNTIME_BLOCK_STORAGE_H
39 void reserve(
void *user_context,
size_t capacity,
bool free_existing =
false);
40 void resize(
void *user_context,
size_t entry_count,
bool realloc =
true);
42 void assign(
void *user_context,
size_t index,
const void *entry_ptr);
43 void insert(
void *user_context,
size_t index,
const void *entry_ptr);
44 void prepend(
void *user_context,
const void *entry_ptr);
45 void append(
void *user_context,
const void *entry_ptr);
46 void remove(
void *user_context,
size_t index);
48 void fill(
void *user_context,
const void *array,
size_t array_size);
49 void insert(
void *user_context,
size_t index,
const void *array,
size_t array_size);
50 void replace(
void *user_context,
size_t index,
const void *array,
size_t array_size);
51 void prepend(
void *user_context,
const void *array,
size_t array_size);
52 void append(
void *user_context,
const void *array,
size_t array_size);
53 void remove(
void *user_context,
size_t index,
size_t entry_count);
58 void clear(
void *user_context);
59 void destroy(
void *user_context);
74 const void *
data()
const;
75 const void *
front()
const;
76 const void *
back()
const;
85 void allocate(
void *user_context,
size_t capacity);
95 : config(cfg), allocator(sma) {
105 :
BlockStorage(nullptr, other.config, other.allocator) {
107 resize(nullptr, other.count);
108 memcpy(this->ptr, other.ptr, count * config.entry_size);
118 if (ptr !=
nullptr) {
121 capacity = count = 0;
128 capacity = count = 0;
136 if (&other !=
this) {
137 config = other.config;
138 resize(
nullptr, other.count);
139 if (count != 0 && other.ptr !=
nullptr) {
150 if (count != other.count) {
157 return !(*
this == other);
161 if (array_size != 0) {
162 resize(user_context, array_size);
169 replace(user_context, index, entry_ptr, 1);
173 insert(user_context, 0, entry_ptr, 1);
177 append(user_context, entry_ptr, 1);
195 new_capacity =
max(new_capacity, count);
197 if ((new_capacity < capacity) && !free_existing) {
198 new_capacity = capacity;
201 allocate(user_context, new_capacity);
205 size_t current_size = capacity;
206 size_t requested_size = entry_count;
208 size_t actual_size = current_size;
209 count = requested_size;
212 if (requested_size > current_size) {
213 actual_size =
max(requested_size,
max(current_size * 3 / 2, minimum_size));
214 }
else if (!realloc) {
218#ifdef DEBUG_RUNTIME_INTERNAL
219 debug(user_context) <<
"BlockStorage: Resize ("
220 <<
"requested_size=" << (
int32_t)requested_size <<
" "
221 <<
"current_size=" << (
int32_t)current_size <<
" "
222 <<
"minimum_size=" << (
int32_t)minimum_size <<
" "
223 <<
"actual_size=" << (
int32_t)actual_size <<
" "
225 <<
"realloc=" << (realloc ?
"true" :
"false") <<
")...\n";
228 allocate(user_context, actual_size);
232 if (capacity > count) {
233 void *new_ptr =
nullptr;
235 size_t actual_bytes = count * config.
entry_size;
236 new_ptr = allocator.
allocate(user_context, actual_bytes);
237 memcpy(new_ptr, ptr, actual_bytes);
246 insert(user_context, index, entry_ptr, 1);
250 remove(user_context, index, 1);
255 const size_t last_index =
size();
256 if (index < (last_index - entry_count)) {
257 size_t dst_offset = index * config.
entry_size;
258 size_t src_offset = (index + entry_count) * config.
entry_size;
259 size_t bytes = (last_index - index - entry_count) * config.
entry_size;
261#ifdef DEBUG_RUNTIME_INTERNAL
262 debug(user_context) <<
"BlockStorage: Remove ("
263 <<
"index=" << (
int32_t)index <<
" "
264 <<
"entry_count=" << (
int32_t)entry_count <<
" "
266 <<
"last_index=" << (
int32_t)last_index <<
" "
267 <<
"src_offset=" << (
int32_t)src_offset <<
" "
268 <<
"dst_offset=" << (
int32_t)dst_offset <<
" "
269 <<
"bytes=" << (
int32_t)bytes <<
")...\n";
273 memmove(dst_ptr, src_ptr, bytes);
275 resize(user_context, last_index - entry_count);
281 size_t remaining = count - index;
284 debug(user_context) <<
"BlockStorage: Replace ("
285 <<
"index=" << (
int32_t)index <<
" "
286 <<
"array_size=" << (
int32_t)array_size <<
" "
288 <<
"offset=" << (
int32_t)offset <<
" "
289 <<
"remaining=" << (
int32_t)remaining <<
" "
290 <<
"capacity=" << (
int32_t)capacity <<
")...\n";
294 size_t copy_count =
min(remaining, array_size);
297 count =
max(count, index + copy_count);
302 const size_t last_index =
size();
303 resize(user_context, last_index + array_size);
304 if (index < last_index) {
305 size_t src_offset = index * config.
entry_size;
306 size_t dst_offset = (index + array_size) * config.
entry_size;
307 size_t bytes = (last_index - index) * config.
entry_size;
310 memmove(dst_ptr, src_ptr, bytes);
312 replace(user_context, index, array, array_size);
316 insert(user_context, 0, array, array_size);
320 const size_t last_index =
size();
321 insert(user_context, last_index, array, array_size);
329 return (count >= capacity);
333 return (index < capacity);
365 size_t index = count - 1;
380 size_t index = count - 1;
384void BlockStorage::allocate(
void *user_context,
size_t new_capacity) {
385 if (new_capacity != capacity) {
387 size_t requested_bytes = new_capacity * config.
entry_size;
389 size_t block_count = (requested_bytes / block_size);
390 block_count += (requested_bytes % block_size) ? 1 : 0;
391 size_t alloc_size = block_count * block_size;
392#ifdef DEBUG_RUNTIME_INTERNAL
393 debug(user_context) <<
"BlockStorage: Allocating ("
394 <<
"requested_bytes=" << (
int32_t)requested_bytes <<
" "
395 <<
"block_size=" << (
int32_t)block_size <<
" "
396 <<
"block_count=" << (
int32_t)block_count <<
" "
397 <<
"alloc_size=" << (
int32_t)alloc_size <<
") ...\n";
399 void *new_ptr = alloc_size ? allocator.
allocate(user_context, alloc_size) :
nullptr;
400 if (count != 0 && ptr !=
nullptr && new_ptr !=
nullptr) {
403 if (ptr !=
nullptr) {
407 capacity = new_capacity;
412const SystemMemoryAllocatorFns &
414 return this->allocator;
419 static Config default_cfg;
432 return native_allocator;
This file declares the routines used by Halide internally in its runtime.
const Config & current_config() const
BlockStorage & operator=(const BlockStorage &other)
void * operator[](size_t index)
logical entry index (returns ptr = data() + (index * stride())
void shrink_to_fit(void *user_context)
void pop_front(void *user_context)
void destroy(void *user_context)
void clear(void *user_context)
static constexpr size_t default_capacity
bool operator!=(const BlockStorage &other) const
void resize(void *user_context, size_t entry_count, bool realloc=true)
static const Config & default_config()
void replace(void *user_context, size_t index, const void *array, size_t array_size)
void prepend(void *user_context, const void *entry_ptr)
void remove(void *user_context, size_t index)
void assign(void *user_context, size_t index, const void *entry_ptr)
void insert(void *user_context, size_t index, const void *entry_ptr)
void initialize(void *user_context, const Config &cfg, const SystemMemoryAllocatorFns &sma=default_allocator())
static const SystemMemoryAllocatorFns & default_allocator()
const SystemMemoryAllocatorFns & current_allocator() const
bool operator==(const BlockStorage &other) const
void append(void *user_context, const void *entry_ptr)
BlockStorage(void *user_context, const Config &cfg, const SystemMemoryAllocatorFns &sma=default_allocator())
bool is_valid(size_t index) const
void fill(void *user_context, const void *array, size_t array_size)
void reserve(void *user_context, size_t capacity, bool free_existing=false)
void pop_back(void *user_context)
ALWAYS_INLINE void * native_system_malloc(void *user_context, size_t bytes)
ALWAYS_INLINE void native_system_free(void *user_context, void *ptr)
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.
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
Expr max(const FuncRef &a, const FuncRef &b)
void * memmove(void *dest, const void *src, size_t n)
signed __INT32_TYPE__ int32_t
void * memcpy(void *s1, const void *s2, size_t n)
int memcmp(const void *s1, const void *s2, size_t n)
unsigned __INT32_TYPE__ uint32_t
#define halide_abort_if_false(user_context, cond)
uint32_t minimum_capacity
DeallocateSystemFn deallocate
AllocateSystemFn allocate