diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 index e206245c..f5ab9d70 100644 --- a/src/lib/libc/stdlib/malloc.3 +++ b/src/lib/libc/stdlib/malloc.3 @@ -33,7 +33,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: malloc.3,v 1.4 1996/09/26 04:19:41 tholo Exp $ +.\" $OpenBSD: malloc.3,v 1.5 1997/05/31 08:47:55 tholo Exp $ .\" .Dd August 27, 1996 .Dt MALLOC 3 @@ -160,6 +160,18 @@ This can substantially aid in compacting memory. ``utrace'' generate entries for ktrace(1) for all operations. Consult the source for this one. +.It X +``xmalloc'' +rather than return failure, +.Xr abort 3 +the program with a diagnostic message on stderr. +It is the intention that this option be set at compile time by +including in the source: +.Bd -literal -offset indent +extern char *malloc_options; +malloc_options = "X"; +.Ed + .It Z ``zero'' fill some junk into the area allocated (see ``J''), except for the exact length the user asked for, which is zeroed. diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index ae88e068..94525adf 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c @@ -8,7 +8,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $"; +static char rcsid[] = "$OpenBSD: malloc.c,v 1.25 1997/05/31 08:47:56 tholo Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -37,14 +37,11 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $ */ #define SOME_JUNK 0xd0 /* as in "Duh" :-) */ -/* - * No user serviceable parts behind this point. - */ - #include #include #include #include +#include #include #include #include @@ -64,6 +61,26 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $ * returned by malloc/realloc. * */ + +#if defined(__i386__) && defined(__FreeBSD__) +# define malloc_pageshift 12U +# define malloc_minsize 16U +#endif /* __i386__ && __FreeBSD__ */ + +#if defined(__sparc__) && !defined(__OpenBSD__) +# define malloc_pageshirt 12U +# define malloc_minsize 16U +# define MAP_ANON (0) +# define USE_DEV_ZERO +# define MADV_FREE MADV_DONTNEED +#endif /* __sparc__ */ + +/* Insert your combination here... */ +#if defined(__FOOCPU__) && defined(__BAROS__) +# define malloc_pageshift 12U +# define malloc_minsize 16U +#endif /* __FOOCPU__ && __BAROS__ */ + #ifdef __OpenBSD__ # if defined(__alpha__) || defined(__m68k__) || defined(__mips__) || \ defined(__i386__) || defined(__m88k__) || defined(__ns32k__) || \ @@ -73,7 +90,21 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.24 1997/04/30 05:52:50 tholo Exp $ # endif /* __i386__ */ #endif /* __OpenBSD__ */ +#ifdef _THREAD_SAFE +#include +static pthread_mutex_t malloc_lock; +#define THREAD_LOCK() pthread_mutex_lock(&malloc_lock) +#define THREAD_UNLOCK() pthread_mutex_unlock(&malloc_lock) +#define THREAD_LOCK_INIT() pthread_mutex_init(&malloc_lock, 0); +#else +#define THREAD_LOCK() +#define THREAD_UNLOCK() +#define THREAD_LOCK_INIT() +#endif + /* + * No user serviceable parts behind this point. + * * This structure describes a page worth of chunks. */ @@ -144,6 +175,18 @@ struct pgfree { #define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask))) #define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo) +/* fd of /dev/zero */ +#ifdef USE_DEV_ZERO +static int fdzero; +#define MMAP_FD fdzero +#define INIT_MMAP() \ + { if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \ + wrterror("open of /dev/zero"); } +#else +#define MMAP_FD (-1) +#define INIT_MMAP() +#endif + /* Set when initialization has been done */ static unsigned malloc_started; @@ -184,6 +227,9 @@ static int malloc_realloc; static int malloc_hint; #endif +/* xmalloc behaviour ? */ +static int malloc_xmalloc; + /* zero fill ? */ static int malloc_zero; @@ -217,6 +263,11 @@ char *malloc_options; /* Name of the current public function */ static char *malloc_func; +/* Macro for mmap */ +#define MMAP(size) \ + mmap((caddr_t)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \ + MMAP_FD, (off_t)0); + /* * Necessary function declarations */ @@ -291,11 +342,11 @@ wrterror(p) char *p; { char *q = " error: "; - suicide = 1; write(2, __progname, strlen(__progname)); write(2, malloc_func, strlen(malloc_func)); write(2, q, strlen(q)); write(2, p, strlen(p)); + suicide = 1; #ifdef MALLOC_STATS if (malloc_stats) malloc_dump(stderr); @@ -393,8 +444,7 @@ extend_pgdir(index) */ /* Get new pages */ - new = (struct pginfo**) mmap(0, i * malloc_pagesize, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE, -1, (off_t)0); + new = (struct pginfo**) MMAP(i * malloc_pagesize); if (new == (struct pginfo **)-1) return 0; @@ -423,6 +473,10 @@ malloc_init () char *p, b[64]; int i, j; + THREAD_LOCK_INIT(); + + INIT_MMAP(); + #ifdef EXTRA_SANITY malloc_junk = 1; #endif /* EXTRA_SANITY */ @@ -464,6 +518,8 @@ malloc_init () case 'u': malloc_utrace = 0; break; case 'U': malloc_utrace = 1; break; #endif /* __FreeBSD__ */ + case 'x': malloc_xmalloc = 0; break; + case 'X': malloc_xmalloc = 1; break; case 'z': malloc_zero = 0; break; case 'Z': malloc_zero = 1; break; default: @@ -491,8 +547,8 @@ malloc_init () #endif /* MALLOC_STATS */ /* Allocate one page for the page directory */ - page_dir = (struct pginfo **) mmap(0, malloc_pagesize, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE, -1, (off_t)0); + page_dir = (struct pginfo **) MMAP(malloc_pagesize); + if (page_dir == (struct pginfo **) -1) wrterror("mmap(2) failed, check limits.\n"); @@ -745,9 +801,6 @@ imalloc(size) size_t size; { void *result; -#ifdef _THREAD_SAFE - int status; -#endif if (!malloc_started) malloc_init(); @@ -783,12 +836,9 @@ irealloc(ptr, size) u_long osize, index; struct pginfo **mp; int i; -#ifdef _THREAD_SAFE - int status; -#endif if (suicide) - return 0; + abort(); if (!malloc_started) { wrtwarning("malloc() has never been called.\n"); @@ -1082,9 +1132,6 @@ ifree(ptr) { struct pginfo *info; int index; -#ifdef _THREAD_SAFE - int status; -#endif /* This is legal */ if (!ptr) @@ -1124,17 +1171,6 @@ ifree(ptr) * These are the public exported interface routines. */ -#ifdef _THREAD_SAFE -#include -#include "pthread_private.h" -static int malloc_lock; -#define THREAD_LOCK() _thread_kern_sig_block(&malloc_lock); -#define THREAD_UNLOCK() _thread_kern_sig_unblock(malloc_lock); -#else -#define THREAD_LOCK() -#define THREAD_UNLOCK() -#endif - static int malloc_active; void * @@ -1153,6 +1189,8 @@ malloc(size_t size) UTRACE(0, size, r); malloc_active--; THREAD_UNLOCK(); + if (malloc_xmalloc && !r) + wrterror("out of memory.\n"); return (r); } @@ -1196,5 +1234,7 @@ realloc(void *ptr, size_t size) UTRACE(ptr, size, r); malloc_active--; THREAD_UNLOCK(); + if (malloc_xmalloc && !r) + wrterror("out of memory.\n"); return (r); }