diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-08-18 06:38:30 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-08-18 06:38:30 -0700 |
commit | b79bc438aadeda878eaa2a26c72129edffba4be7 (patch) | |
tree | 0b5e993bb988e49375d5d6d75549ae7e330932ac | |
parent | 56ff4d38c78dd99873017c075861efefe5428bad (diff) | |
download | txr-b79bc438aadeda878eaa2a26c72129edffba4be7.tar.gz txr-b79bc438aadeda878eaa2a26c72129edffba4be7.tar.bz2 txr-b79bc438aadeda878eaa2a26c72129edffba4be7.zip |
Revising out-of-memory handling.
We don't want to be aborting on OOM, but throwing an
exception.
* lib.c (alloc_error_s): New symbol variable.
(oom_realloc): Global variable removed.
(oom): New static function.
(chk_malloc, chk_malloc_gc_more, chk_calloc, chk_realloc):
Call oom instead of removed oom_realloc handler.
(env): Throw alloc-error rather than error by calling oom.
(obj_init): Initialize alloc_error_s.
(init): Drop function pointer argument; do not
initialize removed oom_realloc.
* lib.h (alloc_error_s): Declared.
(oom_realloc): Declaration removed.
(init): Declaration updated.
* txr.1: Type tree diagram includes alloc-error.
-rw-r--r-- | lib.c | 27 | ||||
-rw-r--r-- | lib.h | 6 | ||||
-rw-r--r-- | txr.1 | 2 | ||||
-rw-r--r-- | txr.c | 15 | ||||
-rw-r--r-- | unwind.c | 1 |
5 files changed, 20 insertions, 31 deletions
@@ -105,7 +105,7 @@ val eof_s, eol_s, assert_s, name_s; val error_s, type_error_s, internal_error_s, panic_s; val numeric_error_s, range_error_s; val query_error_s, file_error_s, process_error_s, syntax_error_s; -val timeout_error_s, system_error_s; +val timeout_error_s, system_error_s, alloc_error_s; val warning_s, defr_warning_s, restart_s, continue_s; val gensym_counter_s, nullify_s, from_list_s, lambda_set_s, length_s; @@ -127,8 +127,6 @@ val year_s, month_s, day_s, hour_s, min_s, sec_s, dst_s, gmtoff_s, zone_s; static val env_list; static val recycled_conses; -mem_t *(*oom_realloc)(mem_t *, size_t); - /* C99 inline instantiations. */ #if __STDC_VERSION__ >= 199901L loc mkloc_fun(val *ptr, val obj); @@ -2602,6 +2600,11 @@ val equal(val left, val right) alloc_bytes_t malloc_bytes; +static void oom(void) +{ + uw_throwf(alloc_error_s, lit("out of memory"), nao); +} + mem_t *chk_malloc(size_t size) { mem_t *ptr = convert(mem_t *, malloc(size)); @@ -2609,7 +2612,7 @@ mem_t *chk_malloc(size_t size) assert (!async_sig_enabled); if (size && ptr == 0) - ptr = convert(mem_t *, oom_realloc(0, size)); + oom(); malloc_bytes += size; return ptr; } @@ -2619,7 +2622,7 @@ mem_t *chk_malloc_gc_more(size_t size) mem_t *ptr = convert(mem_t *, malloc(size)); assert (!async_sig_enabled); if (size && ptr == 0) - ptr = convert(mem_t *, oom_realloc(0, size)); + oom(); return ptr; } @@ -2630,10 +2633,8 @@ mem_t *chk_calloc(size_t n, size_t size) assert (!async_sig_enabled); - if (size && ptr == 0) { - ptr = convert(mem_t *, oom_realloc(0, total)); - memset(ptr, 0, total); - } + if (size && ptr == 0) + oom(); malloc_bytes += total; return ptr; } @@ -2645,7 +2646,7 @@ mem_t *chk_realloc(mem_t *old, size_t size) assert (!async_sig_enabled); if (size != 0 && newptr == 0) - newptr = oom_realloc(old, size); + oom(); malloc_bytes += size; return newptr; } @@ -10129,7 +10130,7 @@ val env(void) wchar_t *iter = env; if (iter == 0) - uw_throwf(error_s, lit("out of memory"), nao); + oom(); for (; *iter; iter += wcslen(iter) + 1) ptail = list_collect(ptail, string(iter)); @@ -10281,6 +10282,7 @@ static void obj_init(void) syntax_error_s = intern(lit("syntax-error"), user_package); system_error_s = intern(lit("system-error"), user_package); timeout_error_s = intern(lit("timeout-error"), user_package); + alloc_error_s = intern(lit("alloc-error"), user_package); assert_s = intern(lit("assert"), user_package); warning_s = intern(lit("warning"), user_package); defr_warning_s = intern(lit("defr-warning"), user_package); @@ -11459,12 +11461,11 @@ static void time_init(void) #endif } -void init(mem_t *(*oom)(mem_t *, size_t), val *stack_bottom) +void init(val *stack_bottom) { int gc_save; gc_save = gc_state(0); - oom_realloc = oom; gc_init(stack_bottom); obj_init(); uw_init(); @@ -467,7 +467,7 @@ extern val eof_s, eol_s, assert_s, name_s; extern val error_s, type_error_s, internal_error_s, panic_s; extern val numeric_error_s, range_error_s; extern val query_error_s, file_error_s, process_error_s, syntax_error_s; -extern val timeout_error_s, system_error_s; +extern val timeout_error_s, system_error_s, alloc_error_s; extern val warning_s, defr_warning_s, restart_s, continue_s; extern val gensym_counter_s; @@ -483,8 +483,6 @@ extern val list_f, less_f, greater_f; extern val prog_string; -extern mem_t *(*oom_realloc)(mem_t *, size_t); - #if HAVE_ULONGLONG_T typedef ulonglong_t alloc_bytes_t; #else @@ -1092,7 +1090,7 @@ val time_parse_local(val format, val string); val time_parse_utc(val format, val string); #endif -void init(mem_t *(*oom_realloc)(mem_t *, size_t), val *stack_bottom); +void init(val *stack_bottom); int compat_fixup(int compat_ver); void dump(val obj, val stream); void d(val obj); @@ -35283,6 +35283,8 @@ subtype of every exception type: | +--- system-error | + +--- alloc-error + | +--- timeout-error | +--- assert @@ -68,19 +68,6 @@ int opt_compat; int opt_dbg_expansion; val stdlib_path; -/* - * Can implement an emergency allocator here from a fixed storage - * pool, which sets an OOM flag. Program can check flag - * and gracefully terminate instead of aborting like this. - */ -static mem_t *oom_realloc_handler(mem_t *old, size_t size) -{ - format(std_error, lit("~a: out of memory\n"), prog_string, nao); - if (opt_print_bindings) - put_line(lit("false"), std_output); - abort(); -} - static void help(void) { val text = lit( @@ -375,7 +362,7 @@ int main(int argc, char **argv) repress_privilege(); progname = utf8_dup_from(argv[0] ? argv[0]: "txr"); progname_u8 = argv[0]; - init(oom_realloc_handler, &stack_bottom); + init(&stack_bottom); match_init(); debug_init(); sysroot_init(); @@ -1038,6 +1038,7 @@ void uw_init(void) uw_register_subtype(file_error_s, error_s); uw_register_subtype(process_error_s, error_s); uw_register_subtype(system_error_s, error_s); + uw_register_subtype(alloc_error_s, error_s); uw_register_subtype(timeout_error_s, error_s); uw_register_subtype(assert_s, error_s); uw_register_subtype(syntax_error_s, error_s); |