Blame src/lib/libast/vmalloc/malloc.c

Packit Service a8c26c
/***********************************************************************
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*               This software is part of the ast package               *
Packit Service a8c26c
*          Copyright (c) 1985-2012 AT&T Intellectual Property          *
Packit Service a8c26c
*                      and is licensed under the                       *
Packit Service a8c26c
*                 Eclipse Public License, Version 1.0                  *
Packit Service a8c26c
*                    by AT&T Intellectual Property                     *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                A copy of the License is available at                 *
Packit Service a8c26c
*          http://www.eclipse.org/org/documents/epl-v10.html           *
Packit Service a8c26c
*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*              Information and Software Systems Research               *
Packit Service a8c26c
*                            AT&T Research                             *
Packit Service a8c26c
*                           Florham Park NJ                            *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                 Glenn Fowler <gsf@research.att.com>                  *
Packit Service a8c26c
*                  David Korn <dgk@research.att.com>                   *
Packit Service a8c26c
*                   Phong Vo <kpv@research.att.com>                    *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
***********************************************************************/
Packit Service a8c26c
#if defined(_UWIN) && defined(_BLD_ast)
Packit Service a8c26c
Packit Service a8c26c
void _STUB_malloc(){}
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
#if _UWIN
Packit Service a8c26c
Packit Service a8c26c
#define calloc		______calloc
Packit Service a8c26c
#define _ast_free	______free
Packit Service a8c26c
#define malloc		______malloc
Packit Service a8c26c
#define mallinfo	______mallinfo
Packit Service a8c26c
#define mallopt		______mallopt
Packit Service a8c26c
#define mstats		______mstats
Packit Service a8c26c
#define realloc		______realloc
Packit Service a8c26c
Packit Service a8c26c
#define _STDLIB_H_	1
Packit Service a8c26c
Packit Service a8c26c
extern int		atexit(void(*)(void));
Packit Service a8c26c
extern char*		getenv(const char*);
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#include	"vmhdr.h"
Packit Service a8c26c
#include	<errno.h>
Packit Service a8c26c
Packit Service a8c26c
#if _UWIN
Packit Service a8c26c
Packit Service a8c26c
#include	<malloc.h>
Packit Service a8c26c
Packit Service a8c26c
#define _map_malloc	1
Packit Service a8c26c
#define _mal_alloca	1
Packit Service a8c26c
Packit Service a8c26c
#undef	calloc
Packit Service a8c26c
#define calloc		_ast_calloc
Packit Service a8c26c
#undef	_ast_free
Packit Service a8c26c
#define free		_ast_free
Packit Service a8c26c
#undef	malloc
Packit Service a8c26c
#define malloc		_ast_malloc
Packit Service a8c26c
#undef	mallinfo
Packit Service a8c26c
typedef struct ______mallinfo Mallinfo_t;
Packit Service a8c26c
#undef	mallopt
Packit Service a8c26c
#undef	mstats
Packit Service a8c26c
typedef struct ______mstats Mstats_t;
Packit Service a8c26c
#undef	realloc
Packit Service a8c26c
#define realloc		_ast_realloc
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
#define F0(f,t0)		f(t0)
Packit Service a8c26c
#define F1(f,t1,a1)		f(t1 a1)
Packit Service a8c26c
#define F2(f,t1,a1,t2,a2)	f(t1 a1, t2 a2)
Packit Service a8c26c
#else
Packit Service a8c26c
#define F0(f,t0)		f()
Packit Service a8c26c
#define F1(f,t1,a1)		f(a1) t1 a1;
Packit Service a8c26c
#define F2(f,t1,a1,t2,a2)	f(a1, a2) t1 a1; t2 a2;
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * define _AST_std_malloc=1 to force the standard malloc
Packit Service a8c26c
 * if _map_malloc is also defined then _ast_malloc etc.
Packit Service a8c26c
 * will simply call malloc etc.
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#if !defined(_AST_std_malloc) && __CYGWIN__
Packit Service a8c26c
#define _AST_std_malloc	1
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
/*	malloc compatibility functions
Packit Service a8c26c
**
Packit Service a8c26c
**	These are aware of debugging/profiling and are driven by the
Packit Service a8c26c
**	VMALLOC_OPTIONS environment variable which is a comma or space
Packit Service a8c26c
**	separated list of [no]name[=value] options:
Packit Service a8c26c
**
Packit Service a8c26c
**	    abort	if Vmregion==Vmdebug then VM_DBABORT is set,
Packit Service a8c26c
**			otherwise _BLD_DEBUG enabled assertions abort()
Packit Service a8c26c
**			on failure
Packit Service a8c26c
**	    break	try sbrk() block allocator first
Packit Service a8c26c
**	    check	if Vmregion==Vmbest then the region is checked every op
Packit Service a8c26c
**	    free	disable addfreelist()
Packit Service a8c26c
**	    keep	disable free -- if code works with this enabled then it
Packit Service a8c26c
**	    		probably accesses free'd data
Packit Service a8c26c
**	    method=m	sets Vmregion=m if not defined, m (Vm prefix optional)
Packit Service a8c26c
**			may be one of { best debug last profile }
Packit Service a8c26c
**	    mmap	try mmap() block allocator first
Packit Service a8c26c
**	    period=n	sets Vmregion=Vmdebug if not defined, if
Packit Service a8c26c
**			Vmregion==Vmdebug the region is checked every n ops
Packit Service a8c26c
**	    profile=f	sets Vmregion=Vmprofile if not set, if
Packit Service a8c26c
**			Vmregion==Vmprofile then profile info printed to file f
Packit Service a8c26c
**	    start=n	sets Vmregion=Vmdebug if not defined, if
Packit Service a8c26c
**			Vmregion==Vmdebug region checking starts after n ops
Packit Service a8c26c
**	    trace=f	enables tracing to file f
Packit Service a8c26c
**	    warn=f	sets Vmregion=Vmdebug if not defined, if
Packit Service a8c26c
**			Vmregion==Vmdebug then warnings printed to file f
Packit Service a8c26c
**	    watch=a	sets Vmregion=Vmdebug if not defined, if
Packit Service a8c26c
**			Vmregion==Vmdebug then address a is watched
Packit Service a8c26c
**
Packit Service a8c26c
**	Output files are created if they don't exist. &n and /dev/fd/n name
Packit Service a8c26c
**	the file descriptor n which must be open for writing. The pattern %p
Packit Service a8c26c
**	in a file name is replaced by the process ID.
Packit Service a8c26c
**
Packit Service a8c26c
**	VMALLOC_OPTIONS combines the features of these previously used env vars:
Packit Service a8c26c
**	    { VMCHECK VMDEBUG VMETHOD VMPROFILE VMTRACE }
Packit Service a8c26c
**
Packit Service a8c26c
**	Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
Packit Service a8c26c
*/
Packit Service a8c26c
Packit Service a8c26c
#if _sys_stat
Packit Service a8c26c
#include	<sys/stat.h>
Packit Service a8c26c
#endif
Packit Service a8c26c
#include	<fcntl.h>
Packit Service a8c26c
Packit Service a8c26c
#ifdef S_IRUSR
Packit Service a8c26c
#define CREAT_MODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
Packit Service a8c26c
#else
Packit Service a8c26c
#define CREAT_MODE	0644
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
static Vmulong_t	_Vmdbstart = 0;
Packit Service a8c26c
static Vmulong_t	_Vmdbcheck = 0;
Packit Service a8c26c
static Vmulong_t	_Vmdbtime = 0;
Packit Service a8c26c
static int		_Vmpffd = -1;
Packit Service a8c26c
Packit Service a8c26c
#if ( !_std_malloc || !_BLD_ast ) && !_AST_std_malloc
Packit Service a8c26c
Packit Service a8c26c
#if !_map_malloc
Packit Service a8c26c
#undef calloc
Packit Service a8c26c
#undef cfree
Packit Service a8c26c
#undef free
Packit Service a8c26c
#undef mallinfo
Packit Service a8c26c
#undef malloc
Packit Service a8c26c
#undef mallopt
Packit Service a8c26c
#undef memalign
Packit Service a8c26c
#undef mstats
Packit Service a8c26c
#undef realloc
Packit Service a8c26c
#undef valloc
Packit Service a8c26c
Packit Service a8c26c
#if _malloc_hook
Packit Service a8c26c
Packit Service a8c26c
#include <malloc.h>
Packit Service a8c26c
Packit Service a8c26c
#undef	calloc
Packit Service a8c26c
#undef	cfree
Packit Service a8c26c
#undef	free
Packit Service a8c26c
#undef	malloc
Packit Service a8c26c
#undef	memalign
Packit Service a8c26c
#undef	realloc
Packit Service a8c26c
Packit Service a8c26c
#define calloc		_ast_calloc
Packit Service a8c26c
#define cfree		_ast_cfree
Packit Service a8c26c
#define free		_ast_free
Packit Service a8c26c
#define malloc		_ast_malloc
Packit Service a8c26c
#define memalign	_ast_memalign
Packit Service a8c26c
#define realloc		_ast_realloc
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _WINIX
Packit Service a8c26c
Packit Service a8c26c
#include <ast_windows.h>
Packit Service a8c26c
Packit Service a8c26c
#if _UWIN
Packit Service a8c26c
Packit Service a8c26c
#define VMRECORD(p)	_vmrecord(p)
Packit Service a8c26c
#define VMBLOCK		{ int _vmblock = _sigblock();
Packit Service a8c26c
#define VMUNBLOCK	_sigunblock(_vmblock); }
Packit Service a8c26c
Packit Service a8c26c
extern int		_sigblock(void);
Packit Service a8c26c
extern void		_sigunblock(int);
Packit Service a8c26c
extern unsigned long	_record[2048];
Packit Service a8c26c
Packit Service a8c26c
__inline Void_t* _vmrecord(Void_t* p)
Packit Service a8c26c
{
Packit Service a8c26c
	register unsigned long	v = ((unsigned long)p)>>16; 
Packit Service a8c26c
Packit Service a8c26c
	_record[v>>5] |= 1<<((v&0x1f));
Packit Service a8c26c
	return p;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
#define getenv(s)	lcl_getenv(s)
Packit Service a8c26c
Packit Service a8c26c
static char*
Packit Service a8c26c
lcl_getenv(const char* s)
Packit Service a8c26c
{
Packit Service a8c26c
	int		n;
Packit Service a8c26c
	static char	buf[512];
Packit Service a8c26c
Packit Service a8c26c
	if (!(n = GetEnvironmentVariable(s, buf, sizeof(buf))) || n > sizeof(buf))
Packit Service a8c26c
		return 0;
Packit Service a8c26c
	return buf;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif /* _UWIN */
Packit Service a8c26c
Packit Service a8c26c
#endif /* _WINIX */
Packit Service a8c26c
Packit Service a8c26c
#ifndef VMRECORD
Packit Service a8c26c
#define VMRECORD(p)	(p)
Packit Service a8c26c
#define VMBLOCK
Packit Service a8c26c
#define VMUNBLOCK
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if defined(__EXPORT__)
Packit Service a8c26c
#define extern		extern __EXPORT__
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
static int		_Vmflinit = 0;
Packit Service a8c26c
#define VMFLINIT() \
Packit Service a8c26c
	{ if(!_Vmflinit)	vmflinit(); \
Packit Service a8c26c
	  if(_Vmdbcheck) \
Packit Service a8c26c
	  { if(_Vmdbtime < _Vmdbstart) _Vmdbtime += 1; \
Packit Service a8c26c
	    else if((_Vmdbtime += 1) < _Vmdbstart) _Vmdbtime = _Vmdbstart; \
Packit Service a8c26c
	    if(_Vmdbtime >= _Vmdbstart && (_Vmdbtime % _Vmdbcheck) == 0 && \
Packit Service a8c26c
	       Vmregion->meth.meth == VM_MTDEBUG) \
Packit Service a8c26c
		vmdbcheck(Vmregion); \
Packit Service a8c26c
	  } \
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
static int vmflinit(void)
Packit Service a8c26c
#else
Packit Service a8c26c
static int vmflinit()
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	char*		file;
Packit Service a8c26c
	int		line;
Packit Service a8c26c
	Void_t*		func;
Packit Service a8c26c
Packit Service a8c26c
	/* this must be done now to avoid any inadvertent recursion (more below) */
Packit Service a8c26c
	_Vmflinit = 1;
Packit Service a8c26c
	VMFLF(Vmregion,file,line,func);
Packit Service a8c26c
Packit Service a8c26c
	/* if getenv() calls malloc(), the options may not affect the eventual region */
Packit Service a8c26c
	VMOPTIONS();
Packit Service a8c26c
Packit Service a8c26c
	/* reset file and line number to correct values for the call */
Packit Service a8c26c
	Vmregion->file = file;
Packit Service a8c26c
	Vmregion->line = line;
Packit Service a8c26c
	Vmregion->func = func;
Packit Service a8c26c
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/* use multiple regions to reduce blocking by concurrent threads  */
Packit Service a8c26c
#if _mem_mmap_anon || _mem_mmap_zero
Packit Service a8c26c
static Vmalloc_t	*Region[64];	/* list of concurrent regions	*/
Packit Service a8c26c
static unsigned int	Regmax = 64;	/* max number of regions	*/
Packit Service a8c26c
#else
Packit Service a8c26c
static Vmalloc_t*	Region[1];	/* list of concurrent regions	*/
Packit Service a8c26c
static unsigned int	Regmax = 0;
Packit Service a8c26c
#endif
Packit Service a8c26c
static unsigned int	Regnum = 0; 	/* current #concurrent regions	*/
Packit Service a8c26c
Packit Service a8c26c
/* statistics */
Packit Service a8c26c
static unsigned int	Regopen = 0; 	/* #allocation calls opened	*/
Packit Service a8c26c
static unsigned int	Reglock = 0; 	/* #allocation calls locked	*/
Packit Service a8c26c
static unsigned int	Regprobe = 0; 	/* #probes to find a region	*/
Packit Service a8c26c
Packit Service a8c26c
int setregmax(int regmax)
Packit Service a8c26c
{
Packit Service a8c26c
	int	oldmax = Regmax;
Packit Service a8c26c
Packit Service a8c26c
	if(regmax >= Regnum && regmax <= sizeof(Region)/sizeof(Region[0]))
Packit Service a8c26c
		Regmax = regmax;
Packit Service a8c26c
Packit Service a8c26c
	return oldmax;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/* return statistics */
Packit Service a8c26c
int _mallocstat(Vmstat_t* st)
Packit Service a8c26c
{
Packit Service a8c26c
	Vmstat_t	vmst;
Packit Service a8c26c
	int		k;
Packit Service a8c26c
Packit Service a8c26c
	if(vmstat(Vmregion, st) < 0) /* add up all stats */
Packit Service a8c26c
		return -1;
Packit Service a8c26c
	for(k = 0; k < Regnum; ++k)
Packit Service a8c26c
	{	if(!Region[k])
Packit Service a8c26c
			continue;
Packit Service a8c26c
		if(vmstat(Region[k], &vmst) < 0 )
Packit Service a8c26c
			return -1;
Packit Service a8c26c
		st->n_busy += vmst.n_busy;
Packit Service a8c26c
		st->n_free += vmst.n_free;
Packit Service a8c26c
		st->s_busy += vmst.s_busy;
Packit Service a8c26c
		st->s_free += vmst.s_free;
Packit Service a8c26c
		st->m_busy += vmst.m_busy;
Packit Service a8c26c
		st->m_free += vmst.m_free;
Packit Service a8c26c
		st->n_seg  += vmst.n_seg;
Packit Service a8c26c
		st->extent += vmst.extent;
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	st->n_region = Regnum+1;
Packit Service a8c26c
	st->n_open = Regopen;
Packit Service a8c26c
	st->n_lock = Reglock;
Packit Service a8c26c
	st->n_probe = Regprobe;
Packit Service a8c26c
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/* find the region that a block was allocated from */
Packit Service a8c26c
static Vmalloc_t* regionof(Void_t* addr)
Packit Service a8c26c
{
Packit Service a8c26c
	int	k;
Packit Service a8c26c
Packit Service a8c26c
#if USE_NATIVE
Packit Service a8c26c
#define CAUTIOUS	1
Packit Service a8c26c
#else
Packit Service a8c26c
#define CAUTIOUS	0
Packit Service a8c26c
#endif
Packit Service a8c26c
	if(CAUTIOUS || Vmregion->meth.meth != VM_MTBEST )
Packit Service a8c26c
	{	/* addr will not be dereferenced here */
Packit Service a8c26c
		if(vmaddr(Vmregion,addr) == 0 )
Packit Service a8c26c
			return Vmregion;
Packit Service a8c26c
		for(k = 0; k < Regnum; ++k)
Packit Service a8c26c
			if(Region[k] && vmaddr(Region[k], addr) == 0 )
Packit Service a8c26c
				return Region[k];
Packit Service a8c26c
		return NIL(Vmalloc_t*);
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
	{	/* fast, but susceptible to bad data */
Packit Service a8c26c
		Vmdata_t *vd = SEG(BLOCK(addr))->vmdt;
Packit Service a8c26c
		if(Vmregion->data == vd )
Packit Service a8c26c
			return Vmregion;
Packit Service a8c26c
		for(k = 0; k < Regnum; ++k)
Packit Service a8c26c
			if(Region[k] && Region[k]->data == vd)
Packit Service a8c26c
				return Region[k];
Packit Service a8c26c
		return NIL(Vmalloc_t*);
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/* manage a cache of free objects */
Packit Service a8c26c
typedef struct _regfree_s
Packit Service a8c26c
{	struct _regfree_s*	next;
Packit Service a8c26c
} Regfree_t;
Packit Service a8c26c
static Regfree_t	*Regfree;
Packit Service a8c26c
Packit Service a8c26c
static void addfreelist(Regfree_t* data)
Packit Service a8c26c
{
Packit Service a8c26c
	unsigned int	k;
Packit Service a8c26c
	Regfree_t	*head;
Packit Service a8c26c
Packit Service a8c26c
	for(k = 0;; ASOLOOP(k) )
Packit Service a8c26c
	{	data->next = head = Regfree;
Packit Service a8c26c
		if(asocasptr(&Regfree, head, data) == (Void_t*)head )
Packit Service a8c26c
			return;
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void clrfreelist()
Packit Service a8c26c
{
Packit Service a8c26c
	Regfree_t	*list, *next;
Packit Service a8c26c
	Vmalloc_t	*vm;
Packit Service a8c26c
Packit Service a8c26c
	if(!(list = Regfree) )
Packit Service a8c26c
		return; /* nothing to do */
Packit Service a8c26c
Packit Service a8c26c
	if(asocasptr(&Regfree, list, NIL(Regfree_t*)) != list )
Packit Service a8c26c
		return; /* somebody else is doing it */
Packit Service a8c26c
Packit Service a8c26c
	for(; list; list = next)
Packit Service a8c26c
	{	next = list->next;
Packit Service a8c26c
		if(vm = regionof((Void_t*)list))
Packit Service a8c26c
		{	if(asocasint(&vm->data->lock, 0, 1) == 0) /* can free this now */
Packit Service a8c26c
			{	(void)(*vm->meth.freef)(vm, (Void_t*)list, 1);
Packit Service a8c26c
				vm->data->lock = 0;
Packit Service a8c26c
			}
Packit Service a8c26c
			else	addfreelist(list); /* ah well, back in the queue */
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/* get a suitable region to allocate from */
Packit Service a8c26c
typedef struct _regdisc_s
Packit Service a8c26c
{	Vmdisc_t	disc;
Packit Service a8c26c
	char		slop[64]; /* to absorb any extra data in Vmdcsystem */
Packit Service a8c26c
} Regdisc_t;
Packit Service a8c26c
Packit Service a8c26c
static int regexcept(Vmalloc_t* vm, int type, Void_t* data, Vmdisc_t* disc)
Packit Service a8c26c
{
Packit Service a8c26c
	if(type == VM_OPEN)
Packit Service a8c26c
	{	if(data) /* make vmopen allocate all memory using discipline */
Packit Service a8c26c
			*(Void_t**)data = data; /* just make it non-NULL */
Packit Service a8c26c
		return 0;
Packit Service a8c26c
	}
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static Vmalloc_t* getregion(int* local)
Packit Service a8c26c
{
Packit Service a8c26c
	Vmalloc_t		*vm;
Packit Service a8c26c
	int			p, pos;
Packit Service a8c26c
Packit Service a8c26c
	static unsigned int	Rand = 0xdeadbeef; /* a cheap prng */
Packit Service a8c26c
#define RAND()			(Rand = Rand*16777617 + 3)
Packit Service a8c26c
Packit Service a8c26c
	clrfreelist();
Packit Service a8c26c
Packit Service a8c26c
	if(Regmax <= 0 )
Packit Service a8c26c
	{	/* uni-process/thread */
Packit Service a8c26c
		*local = 1;
Packit Service a8c26c
		Vmregion->data->lock = 1;
Packit Service a8c26c
		return Vmregion;
Packit Service a8c26c
	}
Packit Service a8c26c
	else if(asocasint(&Vmregion->data->lock, 0, 1) == 0 )
Packit Service a8c26c
	{	/* Vmregion is open, so use it */
Packit Service a8c26c
		*local = 1;
Packit Service a8c26c
		asoincint(&Regopen);
Packit Service a8c26c
		return Vmregion;
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	asoincint(&Regprobe); /* probe Region[] to find an open region */
Packit Service a8c26c
	if(Regnum == 0)
Packit Service a8c26c
		pos = 0;
Packit Service a8c26c
	else for(pos = p = RAND()%Regnum;; )
Packit Service a8c26c
	{	if(Region[p] && asocasint(&Region[p]->data->lock, 0, 1) == 0 )
Packit Service a8c26c
		{	*local = 1;
Packit Service a8c26c
			asoincint(&Regopen);
Packit Service a8c26c
			return Region[p];
Packit Service a8c26c
		}
Packit Service a8c26c
		if((p = (p+1)%Regnum) == pos )
Packit Service a8c26c
			break;
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	/* grab the next open slot for a new region */
Packit Service a8c26c
	while((p = Regnum) < Regmax)
Packit Service a8c26c
		if(asocasint(&Regnum, p, p+1) == p )
Packit Service a8c26c
			break;
Packit Service a8c26c
	if(p < Regmax) /* this slot is now ours */
Packit Service a8c26c
	{	static Regdisc_t	Regdisc;
Packit Service a8c26c
		if(!Regdisc.disc.exceptf) /* one time initialization */
Packit Service a8c26c
		{	GETPAGESIZE(_Vmpagesize);
Packit Service a8c26c
			memcpy(&Regdisc, Vmdcsystem, Vmdcsystem->size);
Packit Service a8c26c
			Regdisc.disc.round = ROUND(_Vmpagesize, 64*1024);
Packit Service a8c26c
			Regdisc.disc.exceptf = regexcept;
Packit Service a8c26c
		}
Packit Service a8c26c
Packit Service a8c26c
		/**/ASSERT(Region[p] == NIL(Vmalloc_t*));
Packit Service a8c26c
		if((vm = vmopen(&Regdisc.disc, Vmbest, VM_SHARE)) != NIL(Vmalloc_t*) )
Packit Service a8c26c
		{	vm->data->lock = 1; /* lock new region now */
Packit Service a8c26c
			*local = 1;
Packit Service a8c26c
			asoincint(&Regopen);
Packit Service a8c26c
			return (Region[p] = vm);
Packit Service a8c26c
		}
Packit Service a8c26c
		else	Region[p] = Vmregion; /* better than nothing */
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	/* must return something */
Packit Service a8c26c
	vm = Region[pos] ? Region[pos] : Vmregion;
Packit Service a8c26c
	if(asocasint(&vm->data->lock, 0, 1) == 0)
Packit Service a8c26c
	{	*local = 1;
Packit Service a8c26c
		asoincint(&Regopen);
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
	{	*local = 0;
Packit Service a8c26c
		asoincint(&Reglock);
Packit Service a8c26c
	}
Packit Service a8c26c
	return vm;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Void_t* calloc(reg size_t n_obj, reg size_t s_obj)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Void_t* calloc(n_obj, s_obj)
Packit Service a8c26c
reg size_t	n_obj;
Packit Service a8c26c
reg size_t	s_obj;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Void_t		*addr;
Packit Service a8c26c
	Vmalloc_t	*vm;
Packit Service a8c26c
	int		local = 0;
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
Packit Service a8c26c
	vm = getregion(&local);
Packit Service a8c26c
	addr = (*vm->meth.resizef)(vm, NIL(Void_t*), n_obj*s_obj, VM_RSZERO, local);
Packit Service a8c26c
	if(local)
Packit Service a8c26c
	{	/**/ASSERT(vm->data->lock == 1);
Packit Service a8c26c
		vm->data->lock = 0;
Packit Service a8c26c
	}
Packit Service a8c26c
	return VMRECORD(addr);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Void_t* malloc(reg size_t size)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Void_t* malloc(size)
Packit Service a8c26c
reg size_t	size;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Void_t		*addr;
Packit Service a8c26c
	Vmalloc_t	*vm;
Packit Service a8c26c
	int		local = 0;
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
Packit Service a8c26c
	vm = getregion(&local);
Packit Service a8c26c
	addr = (*vm->meth.allocf)(vm, size, local);
Packit Service a8c26c
	if(local)
Packit Service a8c26c
	{	/**/ASSERT(vm->data->lock == 1);
Packit Service a8c26c
		vm->data->lock = 0;
Packit Service a8c26c
	}
Packit Service a8c26c
	return VMRECORD(addr);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Void_t* realloc(reg Void_t* data, reg size_t size)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Void_t* realloc(data,size)
Packit Service a8c26c
reg Void_t*	data;	/* block to be reallocated	*/
Packit Service a8c26c
reg size_t	size;	/* new size			*/
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	ssize_t		copy;
Packit Service a8c26c
	Void_t		*addr;
Packit Service a8c26c
	Vmalloc_t	*vm;
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
Packit Service a8c26c
	if(!data)
Packit Service a8c26c
		return malloc(size);
Packit Service a8c26c
	else if((vm = regionof(data)) )
Packit Service a8c26c
	{	if(vm == Vmregion && vm != Vmheap) /* no multiple region usage here */
Packit Service a8c26c
		{	addr = (*vm->meth.resizef)(vm, data, size, VM_RSCOPY|VM_RSMOVE, 0);
Packit Service a8c26c
			return VMRECORD(addr);
Packit Service a8c26c
		}
Packit Service a8c26c
		if(asocasint(&vm->data->lock, 0, 1) == 0 ) /* region is open */
Packit Service a8c26c
		{	addr = (*vm->meth.resizef)(vm, data, size, VM_RSCOPY|VM_RSMOVE, 1);
Packit Service a8c26c
			vm->data->lock = 0;
Packit Service a8c26c
			return VMRECORD(addr);
Packit Service a8c26c
		}
Packit Service a8c26c
		else if(Regmax > 0 && Vmregion == Vmheap && (addr = malloc(size)) )
Packit Service a8c26c
		{	if((copy = SIZE(BLOCK(data))&~BITS) > size )
Packit Service a8c26c
				copy = size;	
Packit Service a8c26c
			memcpy(addr, data, copy);
Packit Service a8c26c
			addfreelist((Regfree_t*)data);
Packit Service a8c26c
			return VMRECORD(addr);
Packit Service a8c26c
		}
Packit Service a8c26c
		else /* this may block but it is the best that we can do now */
Packit Service a8c26c
		{	addr = (*vm->meth.resizef)(vm, data, size, VM_RSCOPY|VM_RSMOVE, 0);
Packit Service a8c26c
			return VMRECORD(addr);
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	else /* not our data */
Packit Service a8c26c
	{
Packit Service a8c26c
#if USE_NATIVE
Packit Service a8c26c
#undef	realloc /* let the native realloc() take care of it */
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
		extern Void_t*	realloc(Void_t*, size_t);
Packit Service a8c26c
#else
Packit Service a8c26c
		extern Void_t*	realloc();
Packit Service a8c26c
#endif
Packit Service a8c26c
		return realloc(data, size);
Packit Service a8c26c
#else 
Packit Service a8c26c
		return NIL(Void_t*);
Packit Service a8c26c
#endif
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern void free(reg Void_t* data)
Packit Service a8c26c
#else
Packit Service a8c26c
extern void free(data)
Packit Service a8c26c
reg Void_t*	data;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Vmalloc_t	*vm;
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
Packit Service a8c26c
	if(!data || (_Vmassert & VM_keep))
Packit Service a8c26c
		return;
Packit Service a8c26c
	else if((vm = regionof(data)) )
Packit Service a8c26c
	{	
Packit Service a8c26c
		if(vm == Vmregion && Vmregion != Vmheap || (_Vmassert & VM_free))
Packit Service a8c26c
			(void)(*vm->meth.freef)(vm, data, 0);
Packit Service a8c26c
		else	addfreelist((Regfree_t*)data);
Packit Service a8c26c
		return;
Packit Service a8c26c
	}
Packit Service a8c26c
	else /* not our data */
Packit Service a8c26c
	{
Packit Service a8c26c
#if USE_NATIVE
Packit Service a8c26c
#undef	free /* let the native free() take care of it */
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
		extern void	free(Void_t*);
Packit Service a8c26c
#else
Packit Service a8c26c
		extern void	free();
Packit Service a8c26c
#endif
Packit Service a8c26c
		free(data);
Packit Service a8c26c
#endif
Packit Service a8c26c
		return;
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern void cfree(reg Void_t* data)
Packit Service a8c26c
#else
Packit Service a8c26c
extern void cfree(data)
Packit Service a8c26c
reg Void_t*	data;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	free(data);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Void_t* memalign(reg size_t align, reg size_t size)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Void_t* memalign(align, size)
Packit Service a8c26c
reg size_t	align;
Packit Service a8c26c
reg size_t	size;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Void_t		*addr;
Packit Service a8c26c
	Vmalloc_t	*vm;
Packit Service a8c26c
	int		local = 0;
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
Packit Service a8c26c
	vm = getregion(&local);
Packit Service a8c26c
	VMBLOCK
Packit Service a8c26c
	addr = (*vm->meth.alignf)(vm, size, align, local);
Packit Service a8c26c
	if(local)
Packit Service a8c26c
	{	/**/ASSERT(vm->data->lock == 1);
Packit Service a8c26c
		vm->data->lock = 0;
Packit Service a8c26c
	}
Packit Service a8c26c
	VMUNBLOCK
Packit Service a8c26c
	return VMRECORD(addr);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern int posix_memalign(reg Void_t **memptr, reg size_t align, reg size_t size)
Packit Service a8c26c
#else
Packit Service a8c26c
extern int posix_memalign(memptr, align, size)
Packit Service a8c26c
reg Void_t**	memptr;
Packit Service a8c26c
reg size_t	align;
Packit Service a8c26c
reg size_t	size;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Void_t	*mem;
Packit Service a8c26c
Packit Service a8c26c
	if(align == 0 || (align%sizeof(Void_t*)) != 0 || ((align-1)&align) != 0 )
Packit Service a8c26c
		return EINVAL;
Packit Service a8c26c
Packit Service a8c26c
	if(!(mem = memalign(align, size)) )
Packit Service a8c26c
		return ENOMEM;
Packit Service a8c26c
Packit Service a8c26c
	*memptr = mem;
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Void_t* valloc(reg size_t size)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Void_t* valloc(size)
Packit Service a8c26c
reg size_t	size;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
Packit Service a8c26c
	GETPAGESIZE(_Vmpagesize);
Packit Service a8c26c
	return VMRECORD(memalign(_Vmpagesize, size));
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Void_t* pvalloc(reg size_t size)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Void_t* pvalloc(size)
Packit Service a8c26c
reg size_t	size;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
Packit Service a8c26c
	GETPAGESIZE(_Vmpagesize);
Packit Service a8c26c
	return VMRECORD(memalign(_Vmpagesize, ROUND(size,_Vmpagesize)) );
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if !_PACKAGE_ast
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
char* strdup(const char* s)
Packit Service a8c26c
#else
Packit Service a8c26c
char* strdup(s)
Packit Service a8c26c
char*	s;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	char	*ns;
Packit Service a8c26c
	size_t	n;
Packit Service a8c26c
Packit Service a8c26c
	if(!s)
Packit Service a8c26c
		return NIL(char*);
Packit Service a8c26c
	else
Packit Service a8c26c
	{	n = strlen(s);
Packit Service a8c26c
		if((ns = malloc(n+1)) )
Packit Service a8c26c
			memcpy(ns,s,n+1);
Packit Service a8c26c
		return ns;
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
#endif /* _PACKAGE_ast */
Packit Service a8c26c
Packit Service a8c26c
#if !_lib_alloca || _mal_alloca
Packit Service a8c26c
#ifndef _stk_down
Packit Service a8c26c
#define _stk_down	0
Packit Service a8c26c
#endif
Packit Service a8c26c
typedef struct _alloca_s	Alloca_t;
Packit Service a8c26c
union _alloca_u
Packit Service a8c26c
{	struct
Packit Service a8c26c
	{	char*		addr;
Packit Service a8c26c
		Alloca_t*	next;
Packit Service a8c26c
	} head;
Packit Service a8c26c
	char	array[ALIGN];
Packit Service a8c26c
};
Packit Service a8c26c
struct _alloca_s
Packit Service a8c26c
{	union _alloca_u	head;
Packit Service a8c26c
	Vmuchar_t	data[1];
Packit Service a8c26c
};
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Void_t* alloca(size_t size)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Void_t* alloca(size)
Packit Service a8c26c
size_t	size;
Packit Service a8c26c
#endif
Packit Service a8c26c
{	char		array[ALIGN];
Packit Service a8c26c
	char*		file;
Packit Service a8c26c
	int		line;
Packit Service a8c26c
	Void_t*		func;
Packit Service a8c26c
	Alloca_t*	f;
Packit Service a8c26c
	Vmalloc_t	*vm;
Packit Service a8c26c
	static Alloca_t* Frame;
Packit Service a8c26c
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
Packit Service a8c26c
	VMFLF(Vmregion,file,line,func); /* save info before freeing frames */
Packit Service a8c26c
Packit Service a8c26c
	while(Frame) /* free unused frames */
Packit Service a8c26c
	{	if(( _stk_down && &array[0] > Frame->head.head.addr) ||
Packit Service a8c26c
		   (!_stk_down && &array[0] < Frame->head.head.addr) )
Packit Service a8c26c
		{	f = Frame; Frame = f->head.head.next;
Packit Service a8c26c
			if((vm = regionof(f)) )
Packit Service a8c26c
				(void)(*vm->meth.freef)(vm, f, 0);
Packit Service a8c26c
			/* else: something bad happened. just keep going */
Packit Service a8c26c
		}
Packit Service a8c26c
		else	break;
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	Vmregion->file = file; /* restore file/line info before allocation */
Packit Service a8c26c
	Vmregion->line = line;
Packit Service a8c26c
	Vmregion->func = func;
Packit Service a8c26c
Packit Service a8c26c
	f = (Alloca_t*)(*Vmregion->meth.allocf)(Vmregion, size+sizeof(Alloca_t)-1, 0);
Packit Service a8c26c
Packit Service a8c26c
	/* if f is NULL, this mimics a stack overflow with a memory error! */
Packit Service a8c26c
	f->head.head.addr = &array[0];
Packit Service a8c26c
	f->head.head.next = Frame;
Packit Service a8c26c
	Frame = f;
Packit Service a8c26c
Packit Service a8c26c
	return (Void_t*)f->data;
Packit Service a8c26c
}
Packit Service a8c26c
#endif /*!_lib_alloca || _mal_alloca*/
Packit Service a8c26c
Packit Service a8c26c
#if _map_malloc
Packit Service a8c26c
Packit Service a8c26c
/* not sure of all the implications -- 0 is conservative for now */
Packit Service a8c26c
#define USE_NATIVE	0	/* native free/realloc on non-vmalloc ptrs */
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
#if _malloc_hook
Packit Service a8c26c
Packit Service a8c26c
static void vm_free_hook(void* ptr, const void* caller)
Packit Service a8c26c
{
Packit Service a8c26c
	free(ptr);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void* vm_malloc_hook(size_t size, const void* caller)
Packit Service a8c26c
{
Packit Service a8c26c
	void*	r;
Packit Service a8c26c
Packit Service a8c26c
	r = malloc(size);
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void* vm_memalign_hook(size_t align, size_t size, const void* caller)
Packit Service a8c26c
{
Packit Service a8c26c
	void*	r;
Packit Service a8c26c
Packit Service a8c26c
	r = memalign(align, size);
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void* vm_realloc_hook(void* ptr, size_t size, const void* caller)
Packit Service a8c26c
{
Packit Service a8c26c
	void*	r;
Packit Service a8c26c
Packit Service a8c26c
	r = realloc(ptr, size);
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void vm_initialize_hook(void)
Packit Service a8c26c
{
Packit Service a8c26c
	__free_hook = vm_free_hook;
Packit Service a8c26c
	__malloc_hook = vm_malloc_hook;
Packit Service a8c26c
	__memalign_hook = vm_memalign_hook;
Packit Service a8c26c
	__realloc_hook = vm_realloc_hook;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
void	(*__malloc_initialize_hook)(void) = vm_initialize_hook;
Packit Service a8c26c
Packit Service a8c26c
#if 0 /* 2012-02-29 this may be needed to cover shared libs */
Packit Service a8c26c
Packit Service a8c26c
void __attribute__ ((constructor)) vm_initialize_initialize_hook(void)
Packit Service a8c26c
{
Packit Service a8c26c
	vm_initialize_hook();
Packit Service a8c26c
	__malloc_initialize_hook = vm_initialize_hook;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
/* intercept _* __* __libc_* variants */
Packit Service a8c26c
Packit Service a8c26c
#if __lib__malloc
Packit Service a8c26c
extern Void_t*	F2(_calloc, size_t,n, size_t,m) { return calloc(n, m); }
Packit Service a8c26c
extern Void_t	F1(_cfree, Void_t*,p) { free(p); }
Packit Service a8c26c
extern Void_t	F1(_free, Void_t*,p) { free(p); }
Packit Service a8c26c
extern Void_t*	F1(_malloc, size_t,n) { return malloc(n); }
Packit Service a8c26c
#if _lib_memalign
Packit Service a8c26c
extern Void_t*	F2(_memalign, size_t,a, size_t,n) { return memalign(a, n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _lib_pvalloc
Packit Service a8c26c
extern Void_t*	F1(_pvalloc, size_t,n) { return pvalloc(n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
extern Void_t*	F2(_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
Packit Service a8c26c
#if _lib_valloc
Packit Service a8c26c
extern Void_t*	F1(_valloc, size_t,n) { return valloc(n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _lib___malloc
Packit Service a8c26c
extern Void_t*	F2(__calloc, size_t,n, size_t,m) { return calloc(n, m); }
Packit Service a8c26c
extern Void_t	F1(__cfree, Void_t*,p) { free(p); }
Packit Service a8c26c
extern Void_t	F1(__free, Void_t*,p) { free(p); }
Packit Service a8c26c
extern Void_t*	F1(__malloc, size_t,n) { return malloc(n); }
Packit Service a8c26c
#if _lib_memalign
Packit Service a8c26c
extern Void_t*	F2(__memalign, size_t,a, size_t,n) { return memalign(a, n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _lib_pvalloc
Packit Service a8c26c
extern Void_t*	F1(__pvalloc, size_t,n) { return pvalloc(n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
extern Void_t*	F2(__realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
Packit Service a8c26c
#if _lib_valloc
Packit Service a8c26c
extern Void_t*	F1(__valloc, size_t,n) { return valloc(n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _lib___libc_malloc
Packit Service a8c26c
extern Void_t*	F2(__libc_calloc, size_t,n, size_t,m) { return calloc(n, m); }
Packit Service a8c26c
extern Void_t	F1(__libc_cfree, Void_t*,p) { free(p); }
Packit Service a8c26c
extern Void_t	F1(__libc_free, Void_t*,p) { free(p); }
Packit Service a8c26c
extern Void_t*	F1(__libc_malloc, size_t,n) { return malloc(n); }
Packit Service a8c26c
#if _lib_memalign
Packit Service a8c26c
extern Void_t*	F2(__libc_memalign, size_t,a, size_t,n) { return memalign(a, n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _lib_pvalloc
Packit Service a8c26c
extern Void_t*	F1(__libc_pvalloc, size_t,n) { return pvalloc(n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
extern Void_t*	F2(__libc_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
Packit Service a8c26c
#if _lib_valloc
Packit Service a8c26c
extern Void_t*	F1(__libc_valloc, size_t,n) { return valloc(n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#endif /* _malloc_hook */
Packit Service a8c26c
Packit Service a8c26c
#endif /* _map_malloc */
Packit Service a8c26c
Packit Service a8c26c
#undef	extern
Packit Service a8c26c
Packit Service a8c26c
#if _hdr_malloc /* need the mallint interface for statistics, etc. */
Packit Service a8c26c
Packit Service a8c26c
#undef	calloc
Packit Service a8c26c
#define calloc		______calloc
Packit Service a8c26c
#undef	cfree
Packit Service a8c26c
#define cfree		______cfree
Packit Service a8c26c
#undef	free
Packit Service a8c26c
#define free		______free
Packit Service a8c26c
#undef	malloc
Packit Service a8c26c
#define malloc		______malloc
Packit Service a8c26c
#undef	pvalloc
Packit Service a8c26c
#define pvalloc		______pvalloc
Packit Service a8c26c
#undef	realloc
Packit Service a8c26c
#define realloc		______realloc
Packit Service a8c26c
#undef	valloc
Packit Service a8c26c
#define valloc		______valloc
Packit Service a8c26c
Packit Service a8c26c
#if !_UWIN
Packit Service a8c26c
Packit Service a8c26c
#include	<malloc.h>
Packit Service a8c26c
Packit Service a8c26c
typedef struct mallinfo Mallinfo_t;
Packit Service a8c26c
typedef struct mstats Mstats_t;
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if defined(__EXPORT__)
Packit Service a8c26c
#define extern		__EXPORT__
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _lib_mallopt
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern int mallopt(int cmd, int value)
Packit Service a8c26c
#else
Packit Service a8c26c
extern int mallopt(cmd, value)
Packit Service a8c26c
int	cmd;
Packit Service a8c26c
int	value;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
#endif /*_lib_mallopt*/
Packit Service a8c26c
Packit Service a8c26c
#if _lib_mallinfo && _mem_arena_mallinfo
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Mallinfo_t mallinfo(void)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Mallinfo_t mallinfo()
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Vmstat_t	sb;
Packit Service a8c26c
	Mallinfo_t	mi;
Packit Service a8c26c
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
	memset(&mi,0,sizeof(mi));
Packit Service a8c26c
	if(vmstat(Vmregion,&sb) >= 0)
Packit Service a8c26c
	{	mi.arena = sb.extent;
Packit Service a8c26c
		mi.ordblks = sb.n_busy+sb.n_free;
Packit Service a8c26c
		mi.uordblks = sb.s_busy;
Packit Service a8c26c
		mi.fordblks = sb.s_free;
Packit Service a8c26c
	}
Packit Service a8c26c
	return mi;
Packit Service a8c26c
}
Packit Service a8c26c
#endif /* _lib_mallinfo */
Packit Service a8c26c
Packit Service a8c26c
#if _lib_mstats && _mem_bytes_total_mstats
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
extern Mstats_t mstats(void)
Packit Service a8c26c
#else
Packit Service a8c26c
extern Mstats_t mstats()
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Vmstat_t	sb;
Packit Service a8c26c
	Mstats_t	ms;
Packit Service a8c26c
Packit Service a8c26c
	VMFLINIT();
Packit Service a8c26c
	memset(&ms,0,sizeof(ms));
Packit Service a8c26c
	if(vmstat(Vmregion,&sb) >= 0)
Packit Service a8c26c
	{	ms.bytes_total = sb.extent;
Packit Service a8c26c
		ms.chunks_used = sb.n_busy;
Packit Service a8c26c
		ms.bytes_used = sb.s_busy;
Packit Service a8c26c
		ms.chunks_free = sb.n_free;
Packit Service a8c26c
		ms.bytes_free = sb.s_free;
Packit Service a8c26c
	}
Packit Service a8c26c
	return ms;
Packit Service a8c26c
}
Packit Service a8c26c
#endif /*_lib_mstats*/
Packit Service a8c26c
Packit Service a8c26c
#undef	extern
Packit Service a8c26c
Packit Service a8c26c
#endif/*_hdr_malloc*/
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * even though there is no malloc override, still provide
Packit Service a8c26c
 * _ast_* counterparts for object compatibility
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#define setregmax(n)
Packit Service a8c26c
Packit Service a8c26c
#undef	calloc
Packit Service a8c26c
extern Void_t*	calloc _ARG_((size_t, size_t));
Packit Service a8c26c
Packit Service a8c26c
#undef	cfree
Packit Service a8c26c
extern void	cfree _ARG_((Void_t*));
Packit Service a8c26c
Packit Service a8c26c
#undef	free
Packit Service a8c26c
extern void	free _ARG_((Void_t*));
Packit Service a8c26c
Packit Service a8c26c
#undef	malloc
Packit Service a8c26c
extern Void_t*	malloc _ARG_((size_t));
Packit Service a8c26c
Packit Service a8c26c
#if _lib_memalign
Packit Service a8c26c
#undef	memalign
Packit Service a8c26c
extern Void_t*	memalign _ARG_((size_t, size_t));
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _lib_pvalloc
Packit Service a8c26c
#undef	pvalloc
Packit Service a8c26c
extern Void_t*	pvalloc _ARG_((size_t));
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#undef	realloc
Packit Service a8c26c
extern Void_t*	realloc _ARG_((Void_t*, size_t));
Packit Service a8c26c
Packit Service a8c26c
#if _lib_valloc
Packit Service a8c26c
#undef	valloc
Packit Service a8c26c
extern Void_t*	valloc _ARG_((size_t));
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if defined(__EXPORT__)
Packit Service a8c26c
#define extern		__EXPORT__
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if !_malloc_hook
Packit Service a8c26c
Packit Service a8c26c
extern Void_t	F1(_ast_free, Void_t*,p) { free(p); }
Packit Service a8c26c
extern Void_t*	F1(_ast_malloc, size_t,n) { return malloc(n); }
Packit Service a8c26c
#if _lib_memalign
Packit Service a8c26c
extern Void_t*	F2(_ast_memalign, size_t,a, size_t,n) { return memalign(a, n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
extern Void_t*	F2(_ast_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
extern Void_t*	F2(_ast_calloc, size_t,n, size_t,m) { return calloc(n, m); }
Packit Service a8c26c
extern Void_t	F1(_ast_cfree, Void_t*,p) { free(p); }
Packit Service a8c26c
#if _lib_pvalloc
Packit Service a8c26c
extern Void_t*	F1(_ast_pvalloc, size_t,n) { return pvalloc(n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _lib_valloc
Packit Service a8c26c
extern Void_t*	F1(_ast_valloc, size_t,n) { return valloc(n); }
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#undef	extern
Packit Service a8c26c
Packit Service a8c26c
#if _hdr_malloc
Packit Service a8c26c
Packit Service a8c26c
#undef	mallinfo
Packit Service a8c26c
#undef	mallopt
Packit Service a8c26c
#undef	mstats
Packit Service a8c26c
Packit Service a8c26c
#define calloc		______calloc
Packit Service a8c26c
#define cfree		______cfree
Packit Service a8c26c
#define free		______free
Packit Service a8c26c
#define malloc		______malloc
Packit Service a8c26c
#define pvalloc		______pvalloc
Packit Service a8c26c
#define realloc		______realloc
Packit Service a8c26c
#define valloc		______valloc
Packit Service a8c26c
Packit Service a8c26c
#if !_UWIN
Packit Service a8c26c
Packit Service a8c26c
#if !_malloc_hook
Packit Service a8c26c
Packit Service a8c26c
#include	<malloc.h>
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
typedef struct mallinfo Mallinfo_t;
Packit Service a8c26c
typedef struct mstats Mstats_t;
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if defined(__EXPORT__)
Packit Service a8c26c
#define extern		__EXPORT__
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _lib_mallopt
Packit Service a8c26c
extern int	F2(_ast_mallopt, int,cmd, int,value) { return mallopt(cmd, value); }
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _lib_mallinfo && _mem_arena_mallinfo
Packit Service a8c26c
extern Mallinfo_t	F0(_ast_mallinfo, void) { return mallinfo(); }
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _lib_mstats && _mem_bytes_total_mstats
Packit Service a8c26c
extern Mstats_t		F0(_ast_mstats, void) { return mstats(); }
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#undef	extern
Packit Service a8c26c
Packit Service a8c26c
#endif /*_hdr_malloc*/
Packit Service a8c26c
Packit Service a8c26c
#endif /*!_std_malloc*/
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
static Vmulong_t atou(char** sp)
Packit Service a8c26c
#else
Packit Service a8c26c
static Vmulong_t atou(sp)
Packit Service a8c26c
char**	sp;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	char*		s = *sp;
Packit Service a8c26c
	Vmulong_t	v = 0;
Packit Service a8c26c
Packit Service a8c26c
	if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X') )
Packit Service a8c26c
	{	for(s += 2; *s; ++s)
Packit Service a8c26c
		{	if(*s >= '0' && *s <= '9')
Packit Service a8c26c
				v = (v << 4) + (*s - '0');
Packit Service a8c26c
			else if(*s >= 'a' && *s <= 'f')
Packit Service a8c26c
				v = (v << 4) + (*s - 'a') + 10;
Packit Service a8c26c
			else if(*s >= 'A' && *s <= 'F')
Packit Service a8c26c
				v = (v << 4) + (*s - 'A') + 10;
Packit Service a8c26c
			else break;
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
	{	for(; *s; ++s)
Packit Service a8c26c
		{	if(*s >= '0' && *s <= '9')
Packit Service a8c26c
				v = v*10 + (*s - '0');
Packit Service a8c26c
			else break;
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	*sp = s;
Packit Service a8c26c
	return v;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
static char* insertpid(char* begs, char* ends)
Packit Service a8c26c
#else
Packit Service a8c26c
static char* insertpid(begs,ends)
Packit Service a8c26c
char*	begs;
Packit Service a8c26c
char*	ends;
Packit Service a8c26c
#endif
Packit Service a8c26c
{	int	pid;
Packit Service a8c26c
	char*	s;
Packit Service a8c26c
Packit Service a8c26c
	if((pid = getpid()) < 0)
Packit Service a8c26c
		return NIL(char*);
Packit Service a8c26c
Packit Service a8c26c
	s = ends;
Packit Service a8c26c
	do
Packit Service a8c26c
	{	if(s == begs)
Packit Service a8c26c
			return NIL(char*);
Packit Service a8c26c
		*--s = '0' + pid%10;
Packit Service a8c26c
	} while((pid /= 10) > 0);
Packit Service a8c26c
	while(s < ends)
Packit Service a8c26c
		*begs++ = *s++;
Packit Service a8c26c
Packit Service a8c26c
	return begs;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#define FD_PRIVATE	(3*OPEN_MAX/4)
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
int _vmfd(int fd)
Packit Service a8c26c
#else
Packit Service a8c26c
int _vmfd(fd)
Packit Service a8c26c
int	fd;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	int	pd;
Packit Service a8c26c
Packit Service a8c26c
	if (fd >= 0)
Packit Service a8c26c
	{
Packit Service a8c26c
		if (fd < FD_PRIVATE && (pd = fcntl(fd, F_DUPFD, FD_PRIVATE)) >= 0)
Packit Service a8c26c
		{
Packit Service a8c26c
			close(fd);
Packit Service a8c26c
			fd = pd;
Packit Service a8c26c
		}
Packit Service a8c26c
#ifdef FD_CLOEXEC
Packit Service a8c26c
		fcntl(fd,  F_SETFD, FD_CLOEXEC);
Packit Service a8c26c
#endif
Packit Service a8c26c
	}
Packit Service a8c26c
	return fd;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
static int createfile(char* file)
Packit Service a8c26c
#else
Packit Service a8c26c
static int createfile(file)
Packit Service a8c26c
char*	file;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	char	buf[1024];
Packit Service a8c26c
	char	*next, *endb;
Packit Service a8c26c
	int	fd;
Packit Service a8c26c
Packit Service a8c26c
	next = buf;
Packit Service a8c26c
	endb = buf + sizeof(buf);
Packit Service a8c26c
	while(*file)
Packit Service a8c26c
	{	if(*file == '%')
Packit Service a8c26c
		{	switch(file[1])
Packit Service a8c26c
			{
Packit Service a8c26c
			case 'p' :
Packit Service a8c26c
				if(!(next = insertpid(next,endb)) )
Packit Service a8c26c
					return -1;
Packit Service a8c26c
				file += 2;
Packit Service a8c26c
				break;
Packit Service a8c26c
			default :
Packit Service a8c26c
				goto copy;
Packit Service a8c26c
			}
Packit Service a8c26c
		}
Packit Service a8c26c
		else
Packit Service a8c26c
		{ copy:
Packit Service a8c26c
			*next++ = *file++;
Packit Service a8c26c
		}
Packit Service a8c26c
Packit Service a8c26c
		if(next >= endb)
Packit Service a8c26c
			return -1;
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	*next = '\0';
Packit Service a8c26c
	file = buf;
Packit Service a8c26c
	if (*file == '&' && *(file += 1) || strncmp(file, "/dev/fd/", 8) == 0 && *(file += 8))
Packit Service a8c26c
		fd = dup((int)atou(&file));
Packit Service a8c26c
	else if (*file)
Packit Service a8c26c
	{
Packit Service a8c26c
#if _PACKAGE_ast
Packit Service a8c26c
		fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, CREAT_MODE);
Packit Service a8c26c
#else
Packit Service a8c26c
		fd = creat(file, CREAT_MODE);
Packit Service a8c26c
#endif
Packit Service a8c26c
		fd = _vmfd(fd);
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
		return -1;
Packit Service a8c26c
#if _PACKAGE_ast
Packit Service a8c26c
#ifdef FD_CLOEXEC
Packit Service a8c26c
	if (fd >= 0)
Packit Service a8c26c
		fcntl(fd, F_SETFD, FD_CLOEXEC);
Packit Service a8c26c
#endif
Packit Service a8c26c
#endif
Packit Service a8c26c
	return fd;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
static void pfprint(void)
Packit Service a8c26c
#else
Packit Service a8c26c
static void pfprint()
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	if(Vmregion->meth.meth == VM_MTPROFILE)
Packit Service a8c26c
		vmprofile(Vmregion,_Vmpffd);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * initialize runtime options from the VMALLOC_OPTIONS env var
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#define COPY(t,e,f)	while ((*t = *f++) && t < e) t++
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
void _vmoptions(void)
Packit Service a8c26c
#else
Packit Service a8c26c
void _vmoptions()
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Vmalloc_t*	vm = 0;
Packit Service a8c26c
	char*		trace = 0;
Packit Service a8c26c
	char*		s;
Packit Service a8c26c
	char*		t;
Packit Service a8c26c
	char*		v;
Packit Service a8c26c
	Vmulong_t	n;
Packit Service a8c26c
	int		fd;
Packit Service a8c26c
	char		buf[1024];
Packit Service a8c26c
Packit Service a8c26c
	_Vmoptions = 1;
Packit Service a8c26c
	t = buf;
Packit Service a8c26c
	v = &buf[sizeof(buf)-1];
Packit Service a8c26c
	if (s = getenv("VMALLOC_OPTIONS"))
Packit Service a8c26c
		COPY(t, v, s);
Packit Service a8c26c
	if (t > buf)
Packit Service a8c26c
	{
Packit Service a8c26c
		*t = 0;
Packit Service a8c26c
		s = buf;
Packit Service a8c26c
		for (;;)
Packit Service a8c26c
		{
Packit Service a8c26c
			while (*s == ',' || *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
Packit Service a8c26c
				s++;
Packit Service a8c26c
			if (!*(t = s))
Packit Service a8c26c
				break;
Packit Service a8c26c
			v = 0;
Packit Service a8c26c
			while (*s)
Packit Service a8c26c
				if (*s == ',' || *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
Packit Service a8c26c
				{
Packit Service a8c26c
					*s++ = 0;
Packit Service a8c26c
					break;
Packit Service a8c26c
				}
Packit Service a8c26c
				else if (!v && *s == '=')
Packit Service a8c26c
				{
Packit Service a8c26c
					*s++ = 0;
Packit Service a8c26c
					if (!*(v = s))
Packit Service a8c26c
						v = 0;
Packit Service a8c26c
				}
Packit Service a8c26c
				else
Packit Service a8c26c
					s++;
Packit Service a8c26c
			if (t[0] == 'n' && t[1] == 'o')
Packit Service a8c26c
				continue;
Packit Service a8c26c
			switch (t[0])
Packit Service a8c26c
			{
Packit Service a8c26c
			case 'a':		/* abort */
Packit Service a8c26c
				if (!vm)
Packit Service a8c26c
					vm = vmopen(Vmdcsystem, Vmdebug, 0);
Packit Service a8c26c
				if (vm && vm->meth.meth == VM_MTDEBUG)
Packit Service a8c26c
					vmset(vm, VM_DBABORT, 1);
Packit Service a8c26c
				else
Packit Service a8c26c
					_Vmassert |= VM_abort;
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 'b':		/* break */
Packit Service a8c26c
				_Vmassert |= VM_break;
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 'c':		/* check */
Packit Service a8c26c
				_Vmassert |= VM_check;
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 'f':		/* free */
Packit Service a8c26c
				_Vmassert |= VM_free;
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 'k':		/* keep */
Packit Service a8c26c
				_Vmassert |= VM_keep;
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 'm':
Packit Service a8c26c
				if (v)
Packit Service a8c26c
					switch (t[1])
Packit Service a8c26c
					{
Packit Service a8c26c
					case 'e': /* method=METHOD */
Packit Service a8c26c
						if (!vm)
Packit Service a8c26c
						{
Packit Service a8c26c
							if ((v[0] == 'V' || v[0] == 'v') && (v[1] == 'M' || v[1] == 'm'))
Packit Service a8c26c
								v += 2;
Packit Service a8c26c
							if (strcmp(v, "debug") == 0)
Packit Service a8c26c
								vm = vmopen(Vmdcsystem, Vmdebug, 0);
Packit Service a8c26c
							else if (strcmp(v, "profile") == 0)
Packit Service a8c26c
								vm = vmopen(Vmdcsystem, Vmprofile, 0);
Packit Service a8c26c
							else if (strcmp(v, "last") == 0)
Packit Service a8c26c
								vm = vmopen(Vmdcsystem, Vmlast, 0);
Packit Service a8c26c
							else if (strcmp(v, "best") == 0)
Packit Service a8c26c
								vm = Vmheap;
Packit Service a8c26c
						}
Packit Service a8c26c
						break;
Packit Service a8c26c
					case 'm': /* mmap */
Packit Service a8c26c
						_Vmassert |= VM_mmap;
Packit Service a8c26c
						break;
Packit Service a8c26c
					}
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 'p':
Packit Service a8c26c
				if (v)
Packit Service a8c26c
					switch (t[1])
Packit Service a8c26c
					{
Packit Service a8c26c
					case 'e':	/* period=<count> */
Packit Service a8c26c
						if (!vm)
Packit Service a8c26c
							vm = vmopen(Vmdcsystem, Vmdebug, 0);
Packit Service a8c26c
						if (vm && vm->meth.meth == VM_MTDEBUG)
Packit Service a8c26c
							_Vmdbcheck = atou(&v);
Packit Service a8c26c
						break;
Packit Service a8c26c
					case 'r':	/* profile=<path> */
Packit Service a8c26c
						if (!vm)
Packit Service a8c26c
							vm = vmopen(Vmdcsystem, Vmprofile, 0);
Packit Service a8c26c
						if (v && vm && vm->meth.meth == VM_MTPROFILE)
Packit Service a8c26c
							_Vmpffd = createfile(v);
Packit Service a8c26c
						break;
Packit Service a8c26c
					}
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 's':		/* start=<count> */
Packit Service a8c26c
				if (!vm)
Packit Service a8c26c
					vm = vmopen(Vmdcsystem, Vmdebug, 0);
Packit Service a8c26c
				if (v && vm && vm->meth.meth == VM_MTDEBUG)
Packit Service a8c26c
					_Vmdbstart = atou(&v);
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 't':		/* trace=<path> */
Packit Service a8c26c
				trace = v;
Packit Service a8c26c
				break;
Packit Service a8c26c
			case 'w':
Packit Service a8c26c
				if (t[1] == 'a')
Packit Service a8c26c
					switch (t[2])
Packit Service a8c26c
					{
Packit Service a8c26c
					case 'r':	/* warn=<path> */
Packit Service a8c26c
						if (!vm)
Packit Service a8c26c
							vm = vmopen(Vmdcsystem, Vmdebug, 0);
Packit Service a8c26c
						if (v && vm && vm->meth.meth == VM_MTDEBUG && (fd = createfile(v)) >= 0)
Packit Service a8c26c
							vmdebug(fd);
Packit Service a8c26c
						break;
Packit Service a8c26c
					case 't':	/* watch=<addr> */
Packit Service a8c26c
						if (!vm)
Packit Service a8c26c
							vm = vmopen(Vmdcsystem, Vmdebug, 0);
Packit Service a8c26c
						if (v && vm && vm->meth.meth == VM_MTDEBUG && (n = atou(&v)) >= 0)
Packit Service a8c26c
							vmdbwatch((Void_t*)n);
Packit Service a8c26c
						break;
Packit Service a8c26c
					}
Packit Service a8c26c
				break;
Packit Service a8c26c
			}
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	/* slip in the new region now so that malloc() will work fine */
Packit Service a8c26c
Packit Service a8c26c
	if (vm)
Packit Service a8c26c
	{
Packit Service a8c26c
		if (vm->meth.meth == VM_MTDEBUG)
Packit Service a8c26c
			_Vmdbcheck = 1;
Packit Service a8c26c
		Vmregion = vm;
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	/* enable tracing -- this currently disables multiple regions */
Packit Service a8c26c
Packit Service a8c26c
	if (trace)
Packit Service a8c26c
	{
Packit Service a8c26c
		setregmax(0);
Packit Service a8c26c
		if ((fd = createfile(trace)) >= 0)
Packit Service a8c26c
		{
Packit Service a8c26c
			vmset(Vmregion, VM_TRACE, 1);
Packit Service a8c26c
			vmtrace(fd);
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	else if (Vmregion != Vmheap || asometh(0, 0)->type == ASO_SIGNAL)
Packit Service a8c26c
		setregmax(0);
Packit Service a8c26c
Packit Service a8c26c
	/* make sure that profile data is output upon exiting */
Packit Service a8c26c
Packit Service a8c26c
	if (vm && vm->meth.meth == VM_MTPROFILE)
Packit Service a8c26c
	{	
Packit Service a8c26c
		if (_Vmpffd < 0)
Packit Service a8c26c
			_Vmpffd = 2;
Packit Service a8c26c
		/* this may wind up calling malloc(), but region is ok now */
Packit Service a8c26c
		atexit(pfprint);
Packit Service a8c26c
	}
Packit Service a8c26c
	else if (_Vmpffd >= 0)
Packit Service a8c26c
	{	
Packit Service a8c26c
		close(_Vmpffd);
Packit Service a8c26c
		_Vmpffd = -1;
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * ast semi-private workaround for system functions
Packit Service a8c26c
 * that misbehave by passing bogus addresses to free()
Packit Service a8c26c
 *
Packit Service a8c26c
 * not prototyped in any header to keep it ast semi-private
Packit Service a8c26c
 *
Packit Service a8c26c
 * to keep malloc() data by disabling free()
Packit Service a8c26c
 *	extern _vmkeep(int);
Packit Service a8c26c
 *	int r = _vmkeep(1);
Packit Service a8c26c
 * and to restore to the previous state
Packit Service a8c26c
 *	(void)_vmkeep(r);
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
int
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
_vmkeep(int v)
Packit Service a8c26c
#else
Packit Service a8c26c
_vmkeep(v)
Packit Service a8c26c
int	v;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
Packit Service a8c26c
	r = !!(_Vmassert & VM_keep);
Packit Service a8c26c
	if (v)
Packit Service a8c26c
		_Vmassert |= VM_keep;
Packit Service a8c26c
	else
Packit Service a8c26c
		_Vmassert &= ~VM_keep;
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif /*_UWIN*/