// 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