futhark-0.22.7: rts/c/context.h
// Start of context.h
// Eventually it would be nice to move the context definition in here
// instead of generating it in the compiler. For now it defines
// various helper functions that must be available.
// Internal functions.
static void set_error(struct futhark_context* ctx, char *error) {
lock_lock(&ctx->error_lock);
if (ctx->error == NULL) {
ctx->error = error;
} else {
free(error);
}
lock_unlock(&ctx->error_lock);
}
// XXX: should be static, but used in ispc_util.h
void lexical_realloc_error(struct futhark_context* ctx, size_t new_size) {
set_error(ctx,
msgprintf("Failed to allocate memory.\nAttempted allocation: %12lld bytes\n",
(long long) new_size));
}
static int lexical_realloc(struct futhark_context *ctx,
unsigned char **ptr,
int64_t *old_size,
int64_t new_size) {
unsigned char *new = realloc(*ptr, (size_t)new_size);
if (new == NULL) {
lexical_realloc_error(ctx, new_size);
return FUTHARK_OUT_OF_MEMORY;
} else {
*ptr = new;
*old_size = new_size;
return FUTHARK_SUCCESS;
}
}
static void free_all_in_free_list(struct futhark_context* ctx) {
fl_mem mem;
free_list_pack(&ctx->free_list);
while (free_list_first(&ctx->free_list, (fl_mem*)&mem) == 0) {
free((void*)mem);
}
}
static int is_small_alloc(size_t size) {
return size < 1024*1024;
}
static void host_alloc(struct futhark_context* ctx,
size_t size, const char* tag, size_t* size_out, void** mem_out) {
if (is_small_alloc(size) || free_list_find(&ctx->free_list, size, tag, size_out, (fl_mem*)mem_out) != 0) {
*size_out = size;
*mem_out = malloc(size);
}
}
static void host_free(struct futhark_context* ctx,
size_t size, const char* tag, void* mem) {
// Small allocations are handled by malloc()s own free list. The
// threshold here is kind of arbitrary, but seems to work OK.
// Larger allocations are mmap()ed/munmapped() every time, which is
// very slow, and Futhark programs tend to use a few very large
// allocations.
if (is_small_alloc(size)) {
free(mem);
} else {
free_list_insert(&ctx->free_list, size, (fl_mem)mem, tag);
}
}
static void context_setup(struct futhark_context *ctx) {
create_lock(&ctx->error_lock);
create_lock(&ctx->lock);
free_list_init(&ctx->free_list);
}
static void context_teardown(struct futhark_context *ctx) {
free_constants(ctx);
free_all_in_free_list(ctx);
free_list_destroy(&ctx->free_list);
free_lock(&ctx->lock);
free_lock(&ctx->error_lock);
}
// End of context.h