diff options
author | Felipe Oliveira Carvalho <felipekde@gmail.com> | 2014-03-27 23:35:27 -0300 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-03-31 07:31:47 -0300 |
commit | de1575f3ea9dd2ab66198537a0a3788fba0e06bb (patch) | |
tree | d7bb3912f589e61db046a87a5189cfa8d8faef9f | |
parent | a87b73ecb236ad4dff968a48b32b7751676cf1b0 (diff) | |
download | rneovim-de1575f3ea9dd2ab66198537a0a3788fba0e06bb.tar.gz rneovim-de1575f3ea9dd2ab66198537a0a3788fba0e06bb.tar.bz2 rneovim-de1575f3ea9dd2ab66198537a0a3788fba0e06bb.zip |
xmalloc() that succeeds or gracefully aborts
-rw-r--r-- | src/misc2.c | 85 | ||||
-rw-r--r-- | src/misc2.h | 2 |
2 files changed, 41 insertions, 46 deletions
diff --git a/src/misc2.c b/src/misc2.c index 21d942e370..5c07ada005 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -642,63 +642,56 @@ char_u *alloc_check(unsigned size) */ char_u *lalloc_clear(long_u size, int message) { - char_u *p; - - p = (lalloc(size, message)); - if (p != NULL) - (void)memset(p, 0, (size_t)size); + char_u *p = lalloc(size, message); + memset(p, 0, (size_t)size); return p; } -/* - * Low level memory allocation function. - * This is used often, KEEP IT FAST! - */ -char_u *lalloc(long_u size, int message) +/// When out of memory: try to release some memfile blocks and +/// if some blocks are released call malloc again. +void try_to_free_memory() { - char_u *p; /* pointer to new storage space */ - static int releasing = FALSE; /* don't do mf_release_all() recursive */ - int try_again; + static bool trying_to_free = false; + // avoid recursive calls + if (trying_to_free) + return; + trying_to_free = true; - /* Safety check for allocating zero bytes */ - if (size == 0) { - /* Don't hide this message */ - emsg_silent = 0; - EMSGN(_("E341: Internal error: lalloc(%ld, )"), size); - return NULL; - } + // free any scrollback text + clear_sb_text(); + // Try to save all buffers and release as many blocks as possible + mf_release_all(); + // cleanup recursive lists/dicts + garbage_collect(); - /* - * Loop when out of memory: Try to release some memfile blocks and - * if some blocks are released call malloc again. - */ - for (;; ) { - if ((p = (char_u *)malloc((size_t)size)) != NULL) { - /* No check for available memory: Just return. */ - goto theend; - } - /* - * Remember that mf_release_all() is being called to avoid an endless - * loop, because mf_release_all() may call alloc() recursively. - */ - if (releasing) - break; - releasing = TRUE; + trying_to_free = false; +} + +void *xmalloc(size_t size) +{ + void *ret = malloc(size); - clear_sb_text(); /* free any scrollback text */ - try_again = mf_release_all(); /* release as many blocks as possible */ - try_again |= garbage_collect(); /* cleanup recursive lists/dicts */ + if (!ret && !size) + ret = malloc(1); - releasing = FALSE; - if (!try_again) - break; + if (!ret) { + try_to_free_memory(); + ret = malloc(size); + if (!ret && !size) + ret = malloc(1); + if (!ret) { + OUT_STR("Vim: Error: Out of memory.\n"); + preserve_exit(); + } } - if (message && p == NULL) - do_outofmem_msg(size); + return ret; +} -theend: - return p; +/// Old low level memory allocation function. Prefer xmalloc() from now on. +char_u *lalloc(long_u size, int message) +{ + return (char_u *)xmalloc((size_t)size); } /* diff --git a/src/misc2.h b/src/misc2.h index d8f13d7640..0e52993412 100644 --- a/src/misc2.h +++ b/src/misc2.h @@ -27,6 +27,8 @@ char_u *alloc(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *alloc_clear(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *alloc_check(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *lalloc_clear(long_u size, int message) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); +void try_to_free_memory(); +void *xmalloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *lalloc(long_u size, int message) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); void do_outofmem_msg(long_u size); void free_all_mem(void); |