lalloc(size_t size, int message)
{
    void	*p;		    // pointer to new storage space
    static int	releasing = FALSE;  // don't do mf_release_all() recursive
    int		try_again;
#if defined(HAVE_AVAIL_MEM)
    static size_t allocated = 0;    // allocated since last avail check
#endif

    // Safety check for allocating zero bytes
    if (size == 0)
    {
	// Don't hide this message
	emsg_silent = 0;
	iemsg(_(e_internal_error_lalloc_zero));
	return NULL;
    }

#ifdef MEM_PROFILE
    mem_pre_alloc_l(&size);
#endif

    // Loop when out of memory: Try to release some memfile blocks and
    // if some blocks are released call malloc again.
    for (;;)
    {
	// Handle three kinds of systems:
	// 1. No check for available memory: Just return.
	// 2. Slow check for available memory: call mch_avail_mem() after
	//    allocating KEEP_ROOM amount of memory.
	// 3. Strict check for available memory: call mch_avail_mem()
	if ((p = malloc(size)) != NULL)
	{
#ifndef HAVE_AVAIL_MEM
	    // 1. No check for available memory: Just return.
	    goto theend;
#else
	    // 2. Slow check for available memory: call mch_avail_mem() after
	    //    allocating (KEEP_ROOM / 2) amount of memory.
	    allocated += size;
	    if (allocated < KEEP_ROOM / 2)
		goto theend;
	    allocated = 0;

	    // 3. check for available memory: call mch_avail_mem()
	    if (mch_avail_mem(TRUE) < KEEP_ROOM_KB && !releasing)
	    {
		free(p);	// System is low... no go!
		p = NULL;
	    }
	    else
		goto theend;
#endif
	}
	// 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;

	clear_sb_text(TRUE);	      // free any scrollback text
	try_again = mf_release_all(); // release as many blocks as possible

	releasing = FALSE;
	if (!try_again)
	    break;
    }

    if (message && p == NULL)
	do_outofmem_msg(size);

theend:
#ifdef MEM_PROFILE
    mem_post_alloc(&p, size);
#endif
    return p;
}
lalloc(size_t size, int message)
{
    void	*p;		     
    static int	releasing = FALSE;   
    int		try_again;
#if defined(HAVE_AVAIL_MEM)
    static size_t allocated = 0;     
#endif

     
    if (size == 0)
    {
	 
	emsg_silent = 0;
	iemsg(_(e_internal_error_lalloc_zero));
	return NULL;
    }

#ifdef MEM_PROFILE
    mem_pre_alloc_l(&size);
#endif

     
     
    for (;;)
    {
	 
	 
	 
	 
	 
	if ((p = malloc(size)) != NULL)
	{
#ifndef HAVE_AVAIL_MEM
	     
	    goto theend;
#else
	     
	     
	    allocated += size;
	    if (allocated < KEEP_ROOM / 2)
		goto theend;
	    allocated = 0;

	     
	    if (mch_avail_mem(TRUE) < KEEP_ROOM_KB && !releasing)
	    {
		free(p);	 
		p = NULL;
	    }
	    else
		goto theend;
#endif
	}
	 
	 
	if (releasing)
	    break;
	releasing = TRUE;

	clear_sb_text(TRUE);	       
	try_again = mf_release_all();  

	releasing = FALSE;
	if (!try_again)
	    break;
    }

    if (message && p == NULL)
	do_outofmem_msg(size);

theend:
#ifdef MEM_PROFILE
    mem_post_alloc(&p, size);
#endif
    return p;
}