From owner-freebsd-hackers Sat Feb 24 12:29: 5 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from flood.ping.uio.no (flood.ping.uio.no [129.240.78.31]) by hub.freebsd.org (Postfix) with ESMTP id 7C0C237B401 for ; Sat, 24 Feb 2001 12:28:59 -0800 (PST) (envelope-from des@ofug.org) Received: (from des@localhost) by flood.ping.uio.no (8.9.3/8.9.3) id VAA56875; Sat, 24 Feb 2001 21:28:50 +0100 (CET) (envelope-from des@ofug.org) X-URL: http://www.ofug.org/~des/ X-Disclaimer: The views expressed in this message do not necessarily coincide with those of any organisation or company with which I am or have been affiliated. To: seebs@plethora.net (Peter Seebach) Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: Setting memory allocators for library functions. References: <200102241643.f1OGhw616627@guild.plethora.net> From: Dag-Erling Smorgrav Date: 24 Feb 2001 21:28:49 +0100 In-Reply-To: seebs@plethora.net's message of "Sat, 24 Feb 2001 10:43:58 -0600" Message-ID: Lines: 65 User-Agent: Gnus/5.0802 (Gnus v5.8.2) Emacs/20.4 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 #include #include #include #include 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