Skip site navigation (1)Skip section navigation (2)
Date:      24 Feb 2001 21:28:49 +0100
From:      Dag-Erling Smorgrav <des@ofug.org>
To:        seebs@plethora.net (Peter Seebach)
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: Setting memory allocators for library functions.
Message-ID:  <xzpg0h37rlq.fsf@flood.ping.uio.no>
In-Reply-To: seebs@plethora.net's message of "Sat, 24 Feb 2001 10:43:58 -0600"
References:  <200102241643.f1OGhw616627@guild.plethora.net>

next in thread | previous in thread | raw e-mail | index | archive | help
seebs@plethora.net (Peter Seebach) writes:
> Is there any hope that, some day, a setting could be provided where a program
> could request that malloc *NOT* overcommit?  There are programs which would
> rather know in advance, and clean up, than be killed abruptly.

Malloc() does not overcommit - the kernel does. Malloc() doesn't know
and doesn't care.

I imagine you could add a compile-time option that forces obreak()
(why do we still use brk()/sbrk()?) to prefault the newly allocated
address space. Or you could write a malloc() implementation that only
uses mmap(), and add a flag value that makes mmap() prefault pages,
and fail if there isn't enough memory available.

None of these solutions are portable, however; the portable way around
memory overcommit is to write a malloc() wrapper that installs a
SIGSEGV handler, then tries to dirty the newly allocated memory, and
fails gracefully if this causes a segfault. Untested code:

#include <errno.h>
#include <setjmp.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>

static sigjmp_buf sigenv;

static void
sigsegv(int sig)
{
    siglongjmp(sigenv, -1);
}

void *
mymalloc(size_t size)
{
    sig_t saved_sig;
    void *p;

    if ((p = malloc(size)) == NULL)
        return NULL;
    if (sigsetjmp(env) == -1) {
        free(p);
        errno = ENOMEM;
        return NULL;
    }
    saved_sig = signal(SIGSEGV, sigsegv);
    bzero(p, size);
    signal(SIGSEGV, saved_sig);
    return p;
}

This probably won't work in threaded applications.

> (To be pedantic, this is a conformance issue.  If the memory isn't actually
> allocated, malloc shouldn't be returning a non-null pointer.)

Address space is allocated, but initially unmapped. Actual pages
aren't faulted in until they're dirtied. Sometimes malloc() will give
you a chunk of memory that's already mapped and you'll be fine, but
sometimes (when allocating beyond what was previously used) it won't.

DES
-- 
Dag-Erling Smorgrav - des@ofug.org

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzpg0h37rlq.fsf>