Malloc flag X makes malloc behave like the canonical xmalloc() wrapper.

Untested support for Solaris from John-Mark Gurney

Reviewed by:	phk
Submitted by:	(partially) John-Mark Gurney <gurney_j@resnet.uoregon.edu>
This commit is contained in:
Poul-Henning Kamp 1997-05-30 20:39:32 +00:00
parent e134b4d4a9
commit 7e2a8bde3e
2 changed files with 69 additions and 19 deletions

View file

@ -34,7 +34,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)malloc.3 8.1 (Berkeley) 6/4/93
.\" $Id: malloc.3,v 1.8 1997/02/22 15:03:10 peter Exp $
.\" $Id: malloc.3,v 1.9 1997/03/22 23:48:12 mpp Exp $
.\"
.Dd August 27, 1996
.Dt MALLOC 3
@ -149,6 +149,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.

View file

@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $Id: malloc.c,v 1.21 1997/02/22 15:03:12 peter Exp $
* $Id: malloc.c,v 1.22 1997/03/18 07:54:24 phk Exp $
*
*/
@ -56,12 +56,32 @@
# define malloc_minsize 16U
#endif /* __i386__ && __FreeBSD__ */
#if defined(__sparc__)
# 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 /* __i386__ && __FreeBSD__ */
#ifdef _THREAD_SAFE
#include <pthread.h>
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.
*/
@ -69,6 +89,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
@ -144,6 +165,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;
@ -180,6 +213,9 @@ static int malloc_realloc;
/* pass the kernel a hint on free pages ? */
static int malloc_hint;
/* xmalloc behaviour ? */
static int malloc_xmalloc;
/* zero fill ? */
static int malloc_zero;
@ -213,6 +249,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, 0);
/*
* Necessary function declarations
*/
@ -285,11 +326,11 @@ static void
wrterror(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);
@ -384,8 +425,7 @@ extend_pgdir(u_long index)
*/
/* Get new pages */
new = (struct pginfo**) mmap(0, i * malloc_pagesize, PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0);
new = (struct pginfo**) MMAP(i * malloc_pagesize);
if (new == (struct pginfo **)-1)
return 0;
@ -414,6 +454,9 @@ malloc_init ()
char *p, b[64];
int i, j;
THREAD_LOCK_INIT();
INIT_MMAP();
#ifdef EXTRA_SANITY
malloc_junk = 1;
@ -447,6 +490,8 @@ malloc_init ()
case 'J': malloc_junk = 1; break;
case 'u': malloc_utrace = 0; break;
case 'U': malloc_utrace = 1; break;
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:
@ -474,8 +519,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, 0);
page_dir = (struct pginfo **) MMAP(malloc_pagesize);
if (page_dir == (struct pginfo **) -1)
wrterror("mmap(2) failed, check limits.\n");
@ -759,7 +804,7 @@ irealloc(void *ptr, size_t size)
int i;
if (suicide)
return 0;
abort();
if (!malloc_started) {
wrtwarning("malloc() has never been called.\n");
@ -1082,17 +1127,6 @@ ifree(void *ptr)
* These are the public exported interface routines.
*/
#ifdef _THREAD_SAFE
#include <pthread.h>
#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 *
@ -1111,6 +1145,8 @@ malloc(size_t size)
UTRACE(0, size, r);
malloc_active--;
THREAD_UNLOCK();
if (malloc_xmalloc && !r)
wrterror("out of memory.\n");
return (r);
}
@ -1154,5 +1190,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);
}