1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2012 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                   Phong Vo <kpv@research.att.com>                    *
20*b30d1939SAndy Fiddaman *                                                                      *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #if defined(_UWIN) && defined(_BLD_ast)
23*b30d1939SAndy Fiddaman 
_STUB_vmdebug()24*b30d1939SAndy Fiddaman void _STUB_vmdebug(){}
25*b30d1939SAndy Fiddaman 
26*b30d1939SAndy Fiddaman #else
27*b30d1939SAndy Fiddaman 
28*b30d1939SAndy Fiddaman #include	"vmhdr.h"
29*b30d1939SAndy Fiddaman 
30*b30d1939SAndy Fiddaman /*	Method to help with debugging. This does rigorous checks on
31*b30d1939SAndy Fiddaman **	addresses and arena integrity.
32*b30d1939SAndy Fiddaman **
33*b30d1939SAndy Fiddaman **	Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
34*b30d1939SAndy Fiddaman */
35*b30d1939SAndy Fiddaman 
36*b30d1939SAndy Fiddaman /* structure to keep track of file names */
37*b30d1939SAndy Fiddaman typedef struct _dbfile_s	Dbfile_t;
38*b30d1939SAndy Fiddaman struct _dbfile_s
39*b30d1939SAndy Fiddaman {	Dbfile_t*	next;
40*b30d1939SAndy Fiddaman 	char		file[1];
41*b30d1939SAndy Fiddaman };
42*b30d1939SAndy Fiddaman static Dbfile_t*	Dbfile;
43*b30d1939SAndy Fiddaman 
44*b30d1939SAndy Fiddaman /* global watch list */
45*b30d1939SAndy Fiddaman #define S_WATCH	32
46*b30d1939SAndy Fiddaman static int	Dbnwatch;
47*b30d1939SAndy Fiddaman static Void_t*	Dbwatch[S_WATCH];
48*b30d1939SAndy Fiddaman 
49*b30d1939SAndy Fiddaman /* types of warnings reported by dbwarn() */
50*b30d1939SAndy Fiddaman #define	DB_CHECK	0
51*b30d1939SAndy Fiddaman #define DB_ALLOC	1
52*b30d1939SAndy Fiddaman #define DB_FREE		2
53*b30d1939SAndy Fiddaman #define DB_RESIZE	3
54*b30d1939SAndy Fiddaman #define DB_WATCH	4
55*b30d1939SAndy Fiddaman #define DB_RESIZED	5
56*b30d1939SAndy Fiddaman 
57*b30d1939SAndy Fiddaman static int Dbinit = 0;
58*b30d1939SAndy Fiddaman #define DBINIT()	(Dbinit ? 0 : (dbinit(), Dbinit=1) )
dbinit()59*b30d1939SAndy Fiddaman static void dbinit()
60*b30d1939SAndy Fiddaman {	int	fd;
61*b30d1939SAndy Fiddaman 	if((fd = vmtrace(-1)) >= 0)
62*b30d1939SAndy Fiddaman 		vmtrace(fd);
63*b30d1939SAndy Fiddaman }
64*b30d1939SAndy Fiddaman 
65*b30d1939SAndy Fiddaman static int	Dbfd = 2;	/* default warning file descriptor */
66*b30d1939SAndy Fiddaman #if __STD_C
vmdebug(int fd)67*b30d1939SAndy Fiddaman int vmdebug(int fd)
68*b30d1939SAndy Fiddaman #else
69*b30d1939SAndy Fiddaman int vmdebug(fd)
70*b30d1939SAndy Fiddaman int	fd;
71*b30d1939SAndy Fiddaman #endif
72*b30d1939SAndy Fiddaman {
73*b30d1939SAndy Fiddaman 	int	old = Dbfd;
74*b30d1939SAndy Fiddaman 	Dbfd = fd;
75*b30d1939SAndy Fiddaman 	return old;
76*b30d1939SAndy Fiddaman }
77*b30d1939SAndy Fiddaman 
78*b30d1939SAndy Fiddaman 
79*b30d1939SAndy Fiddaman /* just an entry point to make it easy to set break point */
80*b30d1939SAndy Fiddaman #if __STD_C
vmdbwarn(Vmalloc_t * vm,char * mesg,int n)81*b30d1939SAndy Fiddaman static void vmdbwarn(Vmalloc_t* vm, char* mesg, int n)
82*b30d1939SAndy Fiddaman #else
83*b30d1939SAndy Fiddaman static void vmdbwarn(vm, mesg, n)
84*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
85*b30d1939SAndy Fiddaman char*		mesg;
86*b30d1939SAndy Fiddaman int		n;
87*b30d1939SAndy Fiddaman #endif
88*b30d1939SAndy Fiddaman {
89*b30d1939SAndy Fiddaman 	reg Vmdata_t*	vd = vm->data;
90*b30d1939SAndy Fiddaman 
91*b30d1939SAndy Fiddaman 	write(Dbfd,mesg,n);
92*b30d1939SAndy Fiddaman 	if(vd->mode&VM_DBABORT)
93*b30d1939SAndy Fiddaman 		abort();
94*b30d1939SAndy Fiddaman }
95*b30d1939SAndy Fiddaman 
96*b30d1939SAndy Fiddaman /* issue a warning of some type */
97*b30d1939SAndy Fiddaman #if __STD_C
dbwarn(Vmalloc_t * vm,Void_t * data,int where,char * file,int line,Void_t * func,int type)98*b30d1939SAndy Fiddaman static void dbwarn(Vmalloc_t* vm, Void_t* data, int where,
99*b30d1939SAndy Fiddaman 		   char* file, int line, Void_t* func, int type)
100*b30d1939SAndy Fiddaman #else
101*b30d1939SAndy Fiddaman static void dbwarn(vm, data, where, file, line, func, type)
102*b30d1939SAndy Fiddaman Vmalloc_t*	vm;	/* region holding the block	*/
103*b30d1939SAndy Fiddaman Void_t*		data;	/* data block			*/
104*b30d1939SAndy Fiddaman int		where;	/* byte that was corrupted	*/
105*b30d1939SAndy Fiddaman char*		file;	/* file where call originates	*/
106*b30d1939SAndy Fiddaman int		line;	/* line number of call		*/
107*b30d1939SAndy Fiddaman Void_t*		func;	/* function called from		*/
108*b30d1939SAndy Fiddaman int		type;	/* operation being done		*/
109*b30d1939SAndy Fiddaman #endif
110*b30d1939SAndy Fiddaman {
111*b30d1939SAndy Fiddaman 	char	buf[1024], *bufp, *endbuf, *s;
112*b30d1939SAndy Fiddaman #define SLOP	64	/* enough for a message and an int */
113*b30d1939SAndy Fiddaman 
114*b30d1939SAndy Fiddaman 	DBINIT();
115*b30d1939SAndy Fiddaman 
116*b30d1939SAndy Fiddaman 	bufp = buf;
117*b30d1939SAndy Fiddaman 	endbuf = buf + sizeof(buf);
118*b30d1939SAndy Fiddaman 
119*b30d1939SAndy Fiddaman 	if(type == DB_ALLOC)
120*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, "alloc error", ':');
121*b30d1939SAndy Fiddaman 	else if(type == DB_FREE)
122*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, "free error", ':');
123*b30d1939SAndy Fiddaman 	else if(type == DB_RESIZE)
124*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, "resize error", ':');
125*b30d1939SAndy Fiddaman 	else if(type == DB_CHECK)
126*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, "corrupted data", ':');
127*b30d1939SAndy Fiddaman 	else if(type == DB_WATCH)
128*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, "alert", ':');
129*b30d1939SAndy Fiddaman 
130*b30d1939SAndy Fiddaman 	/* region info */
131*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, "region", '=');
132*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(vm), 0), ':');
133*b30d1939SAndy Fiddaman 
134*b30d1939SAndy Fiddaman 	if(data)
135*b30d1939SAndy Fiddaman 	{	bufp = (*_Vmstrcpy)(bufp,"block",'=');
136*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp,(*_Vmitoa)(VLONG(data),0),':');
137*b30d1939SAndy Fiddaman 	}
138*b30d1939SAndy Fiddaman 
139*b30d1939SAndy Fiddaman 	if(!data)
140*b30d1939SAndy Fiddaman 	{	if(where == DB_ALLOC)
141*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp, "can't get memory", ':');
142*b30d1939SAndy Fiddaman 		else	bufp = (*_Vmstrcpy)(bufp, "region is locked", ':');
143*b30d1939SAndy Fiddaman 	}
144*b30d1939SAndy Fiddaman 	else if(type == DB_FREE || type == DB_RESIZE)
145*b30d1939SAndy Fiddaman 	{	if(where == 0)
146*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp, "unallocated block", ':');
147*b30d1939SAndy Fiddaman 		else	bufp = (*_Vmstrcpy)(bufp, "already freed", ':');
148*b30d1939SAndy Fiddaman 	}
149*b30d1939SAndy Fiddaman 	else if(type == DB_WATCH)
150*b30d1939SAndy Fiddaman 	{	bufp = (*_Vmstrcpy)(bufp, "size", '=');
151*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)((Vmulong_t)DBSIZE(data),-1), ':');
152*b30d1939SAndy Fiddaman 		if(where == DB_ALLOC)
153*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp,"just allocated", ':');
154*b30d1939SAndy Fiddaman 		else if(where == DB_FREE)
155*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp,"being freed", ':');
156*b30d1939SAndy Fiddaman 		else if(where == DB_RESIZE)
157*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp,"being resized", ':');
158*b30d1939SAndy Fiddaman 		else if(where == DB_RESIZED)
159*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp,"just resized", ':');
160*b30d1939SAndy Fiddaman 	}
161*b30d1939SAndy Fiddaman 	else if(type == DB_CHECK)
162*b30d1939SAndy Fiddaman 	{	bufp = (*_Vmstrcpy)(bufp, "bad byte at", '=');
163*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(where),-1), ':');
164*b30d1939SAndy Fiddaman 		if((s = DBFILE(data)) && (bufp + strlen(s) + SLOP) < endbuf)
165*b30d1939SAndy Fiddaman 		{	bufp = (*_Vmstrcpy)(bufp,"allocated at", '=');
166*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp, s, ',');
167*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp,(*_Vmitoa)(VLONG(DBLINE(data)),-1),':');
168*b30d1939SAndy Fiddaman 		}
169*b30d1939SAndy Fiddaman 	}
170*b30d1939SAndy Fiddaman 
171*b30d1939SAndy Fiddaman 	/* location where offending call originates from */
172*b30d1939SAndy Fiddaman 	if(file && file[0] && line > 0 && (bufp + strlen(file) + SLOP) < endbuf)
173*b30d1939SAndy Fiddaman 	{	bufp = (*_Vmstrcpy)(bufp, "detected at", '=');
174*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, file, ',');
175*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(line),-1), ',');
176*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(func),-1), ':');
177*b30d1939SAndy Fiddaman 	}
178*b30d1939SAndy Fiddaman 
179*b30d1939SAndy Fiddaman 	*bufp++ = '\n';
180*b30d1939SAndy Fiddaman 	*bufp = '\0';
181*b30d1939SAndy Fiddaman 
182*b30d1939SAndy Fiddaman 	vmdbwarn(vm,buf,(int)(bufp-buf));
183*b30d1939SAndy Fiddaman }
184*b30d1939SAndy Fiddaman 
185*b30d1939SAndy Fiddaman /* check for watched address and issue warnings */
186*b30d1939SAndy Fiddaman #if __STD_C
dbwatch(Vmalloc_t * vm,Void_t * data,char * file,int line,Void_t * func,int type)187*b30d1939SAndy Fiddaman static void dbwatch(Vmalloc_t* vm, Void_t* data,
188*b30d1939SAndy Fiddaman 		    char* file, int line, Void_t* func, int type)
189*b30d1939SAndy Fiddaman #else
190*b30d1939SAndy Fiddaman static void dbwatch(vm, data, file, line, func, type)
191*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
192*b30d1939SAndy Fiddaman Void_t*		data;
193*b30d1939SAndy Fiddaman char*		file;
194*b30d1939SAndy Fiddaman int		line;
195*b30d1939SAndy Fiddaman Void_t*		func;
196*b30d1939SAndy Fiddaman int		type;
197*b30d1939SAndy Fiddaman #endif
198*b30d1939SAndy Fiddaman {
199*b30d1939SAndy Fiddaman 	reg int		n;
200*b30d1939SAndy Fiddaman 
201*b30d1939SAndy Fiddaman 	for(n = Dbnwatch; n >= 0; --n)
202*b30d1939SAndy Fiddaman 	{	if(Dbwatch[n] == data)
203*b30d1939SAndy Fiddaman 		{	dbwarn(vm,data,type,file,line,func,DB_WATCH);
204*b30d1939SAndy Fiddaman 			return;
205*b30d1939SAndy Fiddaman 		}
206*b30d1939SAndy Fiddaman 	}
207*b30d1939SAndy Fiddaman }
208*b30d1939SAndy Fiddaman 
209*b30d1939SAndy Fiddaman /* record information about the block */
210*b30d1939SAndy Fiddaman #if __STD_C
dbsetinfo(Vmuchar_t * data,size_t size,char * file,int line)211*b30d1939SAndy Fiddaman static void dbsetinfo(Vmuchar_t* data, size_t size, char* file, int line)
212*b30d1939SAndy Fiddaman #else
213*b30d1939SAndy Fiddaman static void dbsetinfo(data, size, file, line)
214*b30d1939SAndy Fiddaman Vmuchar_t*	data;	/* real address not the one from Vmbest	*/
215*b30d1939SAndy Fiddaman size_t		size;	/* the actual requested size		*/
216*b30d1939SAndy Fiddaman char*		file;	/* file where the request came from	*/
217*b30d1939SAndy Fiddaman int		line;	/* and line number			*/
218*b30d1939SAndy Fiddaman #endif
219*b30d1939SAndy Fiddaman {
220*b30d1939SAndy Fiddaman 	reg Vmuchar_t	*begp, *endp;
221*b30d1939SAndy Fiddaman 	reg Dbfile_t	*last, *db;
222*b30d1939SAndy Fiddaman 
223*b30d1939SAndy Fiddaman 	DBINIT();
224*b30d1939SAndy Fiddaman 
225*b30d1939SAndy Fiddaman 	/* find the file structure */
226*b30d1939SAndy Fiddaman 	if(!file || !file[0])
227*b30d1939SAndy Fiddaman 		db = NIL(Dbfile_t*);
228*b30d1939SAndy Fiddaman 	else
229*b30d1939SAndy Fiddaman 	{	for(last = NIL(Dbfile_t*), db = Dbfile; db; last = db, db = db->next)
230*b30d1939SAndy Fiddaman 			if(strcmp(db->file,file) == 0)
231*b30d1939SAndy Fiddaman 				break;
232*b30d1939SAndy Fiddaman 		if(!db)
233*b30d1939SAndy Fiddaman 		{	db = (Dbfile_t*)vmalloc(Vmheap,sizeof(Dbfile_t)+strlen(file));
234*b30d1939SAndy Fiddaman 			if(db)
235*b30d1939SAndy Fiddaman 			{	(*_Vmstrcpy)(db->file,file,0);
236*b30d1939SAndy Fiddaman 				db->next = Dbfile;
237*b30d1939SAndy Fiddaman 				Dbfile = db;
238*b30d1939SAndy Fiddaman 			}
239*b30d1939SAndy Fiddaman 		}
240*b30d1939SAndy Fiddaman 		else if(last) /* move-to-front heuristic */
241*b30d1939SAndy Fiddaman 		{	last->next = db->next;
242*b30d1939SAndy Fiddaman 			db->next = Dbfile;
243*b30d1939SAndy Fiddaman 			Dbfile = db;
244*b30d1939SAndy Fiddaman 		}
245*b30d1939SAndy Fiddaman 	}
246*b30d1939SAndy Fiddaman 
247*b30d1939SAndy Fiddaman 	DBSETFL(data,(db ? db->file : NIL(char*)),line);
248*b30d1939SAndy Fiddaman 	DBSIZE(data) = size;
249*b30d1939SAndy Fiddaman 	DBSEG(data)  = SEG(DBBLOCK(data));
250*b30d1939SAndy Fiddaman 
251*b30d1939SAndy Fiddaman 	DBHEAD(data,begp,endp);
252*b30d1939SAndy Fiddaman 	while(begp < endp)
253*b30d1939SAndy Fiddaman 		*begp++ = DB_MAGIC;
254*b30d1939SAndy Fiddaman 	DBTAIL(data,begp,endp);
255*b30d1939SAndy Fiddaman 	while(begp < endp)
256*b30d1939SAndy Fiddaman 		*begp++ = DB_MAGIC;
257*b30d1939SAndy Fiddaman }
258*b30d1939SAndy Fiddaman 
259*b30d1939SAndy Fiddaman /* Check to see if an address is in some data block of a region.
260*b30d1939SAndy Fiddaman ** This returns -(offset+1) if block is already freed, +(offset+1)
261*b30d1939SAndy Fiddaman ** if block is live, 0 if no match.
262*b30d1939SAndy Fiddaman */
263*b30d1939SAndy Fiddaman #if __STD_C
dbaddr(Vmalloc_t * vm,Void_t * addr,int local)264*b30d1939SAndy Fiddaman static long dbaddr(Vmalloc_t* vm, Void_t* addr, int local)
265*b30d1939SAndy Fiddaman #else
266*b30d1939SAndy Fiddaman static long dbaddr(vm, addr, local)
267*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
268*b30d1939SAndy Fiddaman Void_t*		addr;
269*b30d1939SAndy Fiddaman int		local;
270*b30d1939SAndy Fiddaman #endif
271*b30d1939SAndy Fiddaman {
272*b30d1939SAndy Fiddaman 	reg Block_t	*b, *endb;
273*b30d1939SAndy Fiddaman 	reg Seg_t	*seg;
274*b30d1939SAndy Fiddaman 	reg Vmuchar_t	*data;
275*b30d1939SAndy Fiddaman 	reg long	offset = -1L;
276*b30d1939SAndy Fiddaman 	reg Vmdata_t	*vd = vm->data;
277*b30d1939SAndy Fiddaman 
278*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
279*b30d1939SAndy Fiddaman 
280*b30d1939SAndy Fiddaman 	b = endb = NIL(Block_t*);
281*b30d1939SAndy Fiddaman 	for(seg = vd->seg; seg; seg = seg->next)
282*b30d1939SAndy Fiddaman 	{	b = SEGBLOCK(seg);
283*b30d1939SAndy Fiddaman 		endb = (Block_t*)(seg->baddr - sizeof(Head_t));
284*b30d1939SAndy Fiddaman 		if((Vmuchar_t*)addr > (Vmuchar_t*)b &&
285*b30d1939SAndy Fiddaman 		   (Vmuchar_t*)addr < (Vmuchar_t*)endb)
286*b30d1939SAndy Fiddaman 			break;
287*b30d1939SAndy Fiddaman 	}
288*b30d1939SAndy Fiddaman 	if(!seg)
289*b30d1939SAndy Fiddaman 		goto done;
290*b30d1939SAndy Fiddaman 
291*b30d1939SAndy Fiddaman 	if(local) /* must be vmfree or vmresize checking address */
292*b30d1939SAndy Fiddaman 	{	if(DBSEG(addr) == seg)
293*b30d1939SAndy Fiddaman 		{	b = DBBLOCK(addr);
294*b30d1939SAndy Fiddaman 			if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
295*b30d1939SAndy Fiddaman 				offset = 0;
296*b30d1939SAndy Fiddaman 			else	offset = -2L;
297*b30d1939SAndy Fiddaman 		}
298*b30d1939SAndy Fiddaman 		goto done;
299*b30d1939SAndy Fiddaman 	}
300*b30d1939SAndy Fiddaman 
301*b30d1939SAndy Fiddaman 	while(b < endb)
302*b30d1939SAndy Fiddaman 	{	data = (Vmuchar_t*)DATA(b);
303*b30d1939SAndy Fiddaman 		if((Vmuchar_t*)addr >= data && (Vmuchar_t*)addr < data+SIZE(b))
304*b30d1939SAndy Fiddaman 		{	if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
305*b30d1939SAndy Fiddaman 			{	data = DB2DEBUG(data);
306*b30d1939SAndy Fiddaman 				if((Vmuchar_t*)addr >= data &&
307*b30d1939SAndy Fiddaman 				   (Vmuchar_t*)addr < data+DBSIZE(data))
308*b30d1939SAndy Fiddaman 					offset = (long)((Vmuchar_t*)addr - data);
309*b30d1939SAndy Fiddaman 			}
310*b30d1939SAndy Fiddaman 			goto done;
311*b30d1939SAndy Fiddaman 		}
312*b30d1939SAndy Fiddaman 
313*b30d1939SAndy Fiddaman 		b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
314*b30d1939SAndy Fiddaman 	}
315*b30d1939SAndy Fiddaman 
316*b30d1939SAndy Fiddaman done:
317*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
318*b30d1939SAndy Fiddaman 	return offset;
319*b30d1939SAndy Fiddaman }
320*b30d1939SAndy Fiddaman 
321*b30d1939SAndy Fiddaman 
322*b30d1939SAndy Fiddaman #if __STD_C
dbsize(Vmalloc_t * vm,Void_t * addr,int local)323*b30d1939SAndy Fiddaman static long dbsize(Vmalloc_t* vm, Void_t* addr, int local)
324*b30d1939SAndy Fiddaman #else
325*b30d1939SAndy Fiddaman static long dbsize(vm, addr, local)
326*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
327*b30d1939SAndy Fiddaman Void_t*		addr;
328*b30d1939SAndy Fiddaman int		local;
329*b30d1939SAndy Fiddaman #endif
330*b30d1939SAndy Fiddaman {
331*b30d1939SAndy Fiddaman 	Block_t		*b, *endb;
332*b30d1939SAndy Fiddaman 	Seg_t		*seg;
333*b30d1939SAndy Fiddaman 	long		size;
334*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
335*b30d1939SAndy Fiddaman 
336*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
337*b30d1939SAndy Fiddaman 
338*b30d1939SAndy Fiddaman 	size = -1L;
339*b30d1939SAndy Fiddaman 	for(seg = vd->seg; seg; seg = seg->next)
340*b30d1939SAndy Fiddaman 	{	b = SEGBLOCK(seg);
341*b30d1939SAndy Fiddaman 		endb = (Block_t*)(seg->baddr - sizeof(Head_t));
342*b30d1939SAndy Fiddaman 		if((Vmuchar_t*)addr <= (Vmuchar_t*)b ||
343*b30d1939SAndy Fiddaman 		   (Vmuchar_t*)addr >= (Vmuchar_t*)endb)
344*b30d1939SAndy Fiddaman 			continue;
345*b30d1939SAndy Fiddaman 		while(b < endb)
346*b30d1939SAndy Fiddaman 		{	if(addr == (Void_t*)DB2DEBUG(DATA(b)))
347*b30d1939SAndy Fiddaman 			{	if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
348*b30d1939SAndy Fiddaman 					size = (long)DBSIZE(addr);
349*b30d1939SAndy Fiddaman 				goto done;
350*b30d1939SAndy Fiddaman 			}
351*b30d1939SAndy Fiddaman 
352*b30d1939SAndy Fiddaman 			b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
353*b30d1939SAndy Fiddaman 		}
354*b30d1939SAndy Fiddaman 	}
355*b30d1939SAndy Fiddaman 
356*b30d1939SAndy Fiddaman done:
357*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
358*b30d1939SAndy Fiddaman 	return size;
359*b30d1939SAndy Fiddaman }
360*b30d1939SAndy Fiddaman 
361*b30d1939SAndy Fiddaman #if __STD_C
dballoc(Vmalloc_t * vm,size_t size,int local)362*b30d1939SAndy Fiddaman static Void_t* dballoc(Vmalloc_t* vm, size_t size, int local)
363*b30d1939SAndy Fiddaman #else
364*b30d1939SAndy Fiddaman static Void_t* dballoc(vm, size, local)
365*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
366*b30d1939SAndy Fiddaman size_t		size;
367*b30d1939SAndy Fiddaman int		local;
368*b30d1939SAndy Fiddaman #endif
369*b30d1939SAndy Fiddaman {
370*b30d1939SAndy Fiddaman 	size_t		s;
371*b30d1939SAndy Fiddaman 	Vmuchar_t	*data;
372*b30d1939SAndy Fiddaman 	char		*file;
373*b30d1939SAndy Fiddaman 	int		line;
374*b30d1939SAndy Fiddaman 	Void_t		*func;
375*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
376*b30d1939SAndy Fiddaman 	VMFLF(vm,file,line,func);
377*b30d1939SAndy Fiddaman 
378*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
379*b30d1939SAndy Fiddaman 
380*b30d1939SAndy Fiddaman 	if(vd->mode&VM_DBCHECK)
381*b30d1939SAndy Fiddaman 		vmdbcheck(vm);
382*b30d1939SAndy Fiddaman 
383*b30d1939SAndy Fiddaman 	s = ROUND(size,ALIGN) + DB_EXTRA;
384*b30d1939SAndy Fiddaman 	if(s < sizeof(Body_t))	/* no tiny blocks during Vmdebug */
385*b30d1939SAndy Fiddaman 		s = sizeof(Body_t);
386*b30d1939SAndy Fiddaman 
387*b30d1939SAndy Fiddaman 	if(!(data = (Vmuchar_t*)KPVALLOC(vm,s,(*(Vmbest->allocf))) ) )
388*b30d1939SAndy Fiddaman 	{	dbwarn(vm,NIL(Vmuchar_t*),DB_ALLOC,file,line,func,DB_ALLOC);
389*b30d1939SAndy Fiddaman 		goto done;
390*b30d1939SAndy Fiddaman 	}
391*b30d1939SAndy Fiddaman 
392*b30d1939SAndy Fiddaman 	data = DB2DEBUG(data);
393*b30d1939SAndy Fiddaman 	dbsetinfo(data,size,file,line);
394*b30d1939SAndy Fiddaman 
395*b30d1939SAndy Fiddaman 	if((vd->mode&VM_TRACE) && _Vmtrace)
396*b30d1939SAndy Fiddaman 	{	vm->file = file; vm->line = line; vm->func = func;
397*b30d1939SAndy Fiddaman 		(*_Vmtrace)(vm,NIL(Vmuchar_t*),data,size,0);
398*b30d1939SAndy Fiddaman 	}
399*b30d1939SAndy Fiddaman 
400*b30d1939SAndy Fiddaman 	if(Dbnwatch > 0 )
401*b30d1939SAndy Fiddaman 		dbwatch(vm,data,file,line,func,DB_ALLOC);
402*b30d1939SAndy Fiddaman 
403*b30d1939SAndy Fiddaman done:
404*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
405*b30d1939SAndy Fiddaman 
406*b30d1939SAndy Fiddaman 	return (Void_t*)data;
407*b30d1939SAndy Fiddaman }
408*b30d1939SAndy Fiddaman 
409*b30d1939SAndy Fiddaman 
410*b30d1939SAndy Fiddaman #if __STD_C
dbfree(Vmalloc_t * vm,Void_t * data,int local)411*b30d1939SAndy Fiddaman static int dbfree(Vmalloc_t* vm, Void_t* data, int local )
412*b30d1939SAndy Fiddaman #else
413*b30d1939SAndy Fiddaman static int dbfree(vm, data, local )
414*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
415*b30d1939SAndy Fiddaman Void_t*		data;
416*b30d1939SAndy Fiddaman int		local;
417*b30d1939SAndy Fiddaman #endif
418*b30d1939SAndy Fiddaman {
419*b30d1939SAndy Fiddaman 	char		*file;
420*b30d1939SAndy Fiddaman 	int		line;
421*b30d1939SAndy Fiddaman 	Void_t		*func;
422*b30d1939SAndy Fiddaman 	long		offset;
423*b30d1939SAndy Fiddaman 	int		rv, *ip, *endip;
424*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
425*b30d1939SAndy Fiddaman 	VMFLF(vm,file,line,func);
426*b30d1939SAndy Fiddaman 
427*b30d1939SAndy Fiddaman 	if(!data)
428*b30d1939SAndy Fiddaman 		return 0;
429*b30d1939SAndy Fiddaman 
430*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
431*b30d1939SAndy Fiddaman 
432*b30d1939SAndy Fiddaman 	if(vd->mode&VM_DBCHECK)
433*b30d1939SAndy Fiddaman 		vmdbcheck(vm);
434*b30d1939SAndy Fiddaman 
435*b30d1939SAndy Fiddaman 	if((offset = KPVADDR(vm,data,dbaddr)) != 0)
436*b30d1939SAndy Fiddaman 	{	dbwarn(vm,(Vmuchar_t*)data,offset == -1L ? 0 : 1,file,line,func,DB_FREE);
437*b30d1939SAndy Fiddaman 		rv = -1;
438*b30d1939SAndy Fiddaman 	}
439*b30d1939SAndy Fiddaman 	else
440*b30d1939SAndy Fiddaman 	{	if(Dbnwatch > 0)
441*b30d1939SAndy Fiddaman 			dbwatch(vm,data,file,line,func,DB_FREE);
442*b30d1939SAndy Fiddaman 
443*b30d1939SAndy Fiddaman 		if((vd->mode&VM_TRACE) && _Vmtrace)
444*b30d1939SAndy Fiddaman 		{	vm->file = file; vm->line = line; vm->func = func;
445*b30d1939SAndy Fiddaman 			(*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*),DBSIZE(data),0);
446*b30d1939SAndy Fiddaman 		}
447*b30d1939SAndy Fiddaman 
448*b30d1939SAndy Fiddaman 		/* clear free space */
449*b30d1939SAndy Fiddaman 		ip = (int*)data;
450*b30d1939SAndy Fiddaman 		endip = ip + (DBSIZE(data)+sizeof(int)-1)/sizeof(int);
451*b30d1939SAndy Fiddaman 		while(ip < endip)
452*b30d1939SAndy Fiddaman 			*ip++ = 0;
453*b30d1939SAndy Fiddaman 
454*b30d1939SAndy Fiddaman 		rv = KPVFREE((vm), (Void_t*)DB2BEST(data), (*Vmbest->freef));
455*b30d1939SAndy Fiddaman 	}
456*b30d1939SAndy Fiddaman 
457*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
458*b30d1939SAndy Fiddaman 	return rv;
459*b30d1939SAndy Fiddaman }
460*b30d1939SAndy Fiddaman 
461*b30d1939SAndy Fiddaman /*	Resizing an existing block */
462*b30d1939SAndy Fiddaman #if __STD_C
dbresize(Vmalloc_t * vm,Void_t * addr,reg size_t size,int type,int local)463*b30d1939SAndy Fiddaman static Void_t* dbresize(Vmalloc_t* vm, Void_t* addr, reg size_t size, int type, int local)
464*b30d1939SAndy Fiddaman #else
465*b30d1939SAndy Fiddaman static Void_t* dbresize(vm, addr, size, type, local)
466*b30d1939SAndy Fiddaman Vmalloc_t*	vm;	/* region allocating from	*/
467*b30d1939SAndy Fiddaman Void_t*		addr;	/* old block of data		*/
468*b30d1939SAndy Fiddaman reg size_t	size;	/* new size			*/
469*b30d1939SAndy Fiddaman int		type;	/* !=0 for movable, >0 for copy	*/
470*b30d1939SAndy Fiddaman int		local;
471*b30d1939SAndy Fiddaman #endif
472*b30d1939SAndy Fiddaman {
473*b30d1939SAndy Fiddaman 	Vmuchar_t	*data;
474*b30d1939SAndy Fiddaman 	long		offset;
475*b30d1939SAndy Fiddaman 	size_t		s, oldsize;
476*b30d1939SAndy Fiddaman 	char		*file, *oldfile;
477*b30d1939SAndy Fiddaman 	int		line, oldline;
478*b30d1939SAndy Fiddaman 	Void_t		*func;
479*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
480*b30d1939SAndy Fiddaman 	VMFLF(vm,file,line,func);
481*b30d1939SAndy Fiddaman 
482*b30d1939SAndy Fiddaman 	if(!addr)
483*b30d1939SAndy Fiddaman 	{	vm->file = file; vm->line = line;
484*b30d1939SAndy Fiddaman 		data = (Vmuchar_t*)dballoc(vm, size, local);
485*b30d1939SAndy Fiddaman 		if(data && (type&VM_RSZERO) )
486*b30d1939SAndy Fiddaman 			memset((Void_t*)data, 0, size);
487*b30d1939SAndy Fiddaman 		return data;
488*b30d1939SAndy Fiddaman 	}
489*b30d1939SAndy Fiddaman 	if(size == 0)
490*b30d1939SAndy Fiddaman 	{	vm->file = file; vm->line = line;
491*b30d1939SAndy Fiddaman 		(void)dbfree(vm, addr, local);
492*b30d1939SAndy Fiddaman 		return NIL(Void_t*);
493*b30d1939SAndy Fiddaman 	}
494*b30d1939SAndy Fiddaman 
495*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
496*b30d1939SAndy Fiddaman 
497*b30d1939SAndy Fiddaman 	if(vd->mode&VM_DBCHECK)
498*b30d1939SAndy Fiddaman 		vmdbcheck(vm);
499*b30d1939SAndy Fiddaman 
500*b30d1939SAndy Fiddaman 	if((offset = KPVADDR(vm,addr,dbaddr)) != 0)
501*b30d1939SAndy Fiddaman 	{	dbwarn(vm,(Vmuchar_t*)addr,offset == -1L ? 0 : 1,file,line,func,DB_RESIZE);
502*b30d1939SAndy Fiddaman 		data = NIL(Vmuchar_t*);
503*b30d1939SAndy Fiddaman 	}
504*b30d1939SAndy Fiddaman 	else
505*b30d1939SAndy Fiddaman 	{	if(Dbnwatch > 0)
506*b30d1939SAndy Fiddaman 			dbwatch(vm,addr,file,line,func,DB_RESIZE);
507*b30d1939SAndy Fiddaman 
508*b30d1939SAndy Fiddaman 		/* Vmbest data block */
509*b30d1939SAndy Fiddaman 		data = DB2BEST(addr);
510*b30d1939SAndy Fiddaman 		oldsize = DBSIZE(addr);
511*b30d1939SAndy Fiddaman 		oldfile = DBFILE(addr);
512*b30d1939SAndy Fiddaman 		oldline = DBLINE(addr);
513*b30d1939SAndy Fiddaman 
514*b30d1939SAndy Fiddaman 		/* do the resize */
515*b30d1939SAndy Fiddaman 		s = ROUND(size,ALIGN) + DB_EXTRA;
516*b30d1939SAndy Fiddaman 		if(s < sizeof(Body_t))
517*b30d1939SAndy Fiddaman 			s = sizeof(Body_t);
518*b30d1939SAndy Fiddaman 		data = (Vmuchar_t*)KPVRESIZE(vm,(Void_t*)data,s,
519*b30d1939SAndy Fiddaman 					 (type&~VM_RSZERO),(*(Vmbest->resizef)) );
520*b30d1939SAndy Fiddaman 		if(!data) /* failed, reset data for old block */
521*b30d1939SAndy Fiddaman 		{	dbwarn(vm,NIL(Vmuchar_t*),DB_ALLOC,file,line,func,DB_RESIZE);
522*b30d1939SAndy Fiddaman 			dbsetinfo((Vmuchar_t*)addr,oldsize,oldfile,oldline);
523*b30d1939SAndy Fiddaman 		}
524*b30d1939SAndy Fiddaman 		else
525*b30d1939SAndy Fiddaman 		{	data = DB2DEBUG(data);
526*b30d1939SAndy Fiddaman 			dbsetinfo(data,size,file,line);
527*b30d1939SAndy Fiddaman 
528*b30d1939SAndy Fiddaman 			if((vd->mode&VM_TRACE) && _Vmtrace)
529*b30d1939SAndy Fiddaman 			{	vm->file = file; vm->line = line;
530*b30d1939SAndy Fiddaman 				(*_Vmtrace)(vm,(Vmuchar_t*)addr,data,size,0);
531*b30d1939SAndy Fiddaman 			}
532*b30d1939SAndy Fiddaman 			if(Dbnwatch > 0)
533*b30d1939SAndy Fiddaman 				dbwatch(vm,data,file,line,func,DB_RESIZED);
534*b30d1939SAndy Fiddaman 		}
535*b30d1939SAndy Fiddaman 
536*b30d1939SAndy Fiddaman 		if(data && (type&VM_RSZERO) && size > oldsize)
537*b30d1939SAndy Fiddaman 		{	Vmuchar_t *d = data+oldsize, *ed = data+size;
538*b30d1939SAndy Fiddaman 			do { *d++ = 0; } while(d < ed);
539*b30d1939SAndy Fiddaman 		}
540*b30d1939SAndy Fiddaman 	}
541*b30d1939SAndy Fiddaman 
542*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
543*b30d1939SAndy Fiddaman 
544*b30d1939SAndy Fiddaman 	return (Void_t*)data;
545*b30d1939SAndy Fiddaman }
546*b30d1939SAndy Fiddaman 
547*b30d1939SAndy Fiddaman /* compact any residual free space */
548*b30d1939SAndy Fiddaman #if __STD_C
dbcompact(Vmalloc_t * vm,int local)549*b30d1939SAndy Fiddaman static int dbcompact(Vmalloc_t* vm, int local)
550*b30d1939SAndy Fiddaman #else
551*b30d1939SAndy Fiddaman static int dbcompact(vm, local)
552*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
553*b30d1939SAndy Fiddaman int		local;
554*b30d1939SAndy Fiddaman #endif
555*b30d1939SAndy Fiddaman {
556*b30d1939SAndy Fiddaman 	return (*(Vmbest->compactf))(vm, local);
557*b30d1939SAndy Fiddaman }
558*b30d1939SAndy Fiddaman 
559*b30d1939SAndy Fiddaman /* check for memory overwrites over all live blocks */
560*b30d1939SAndy Fiddaman #if __STD_C
vmdbcheck(Vmalloc_t * vm)561*b30d1939SAndy Fiddaman int vmdbcheck(Vmalloc_t* vm)
562*b30d1939SAndy Fiddaman #else
563*b30d1939SAndy Fiddaman int vmdbcheck(vm)
564*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
565*b30d1939SAndy Fiddaman #endif
566*b30d1939SAndy Fiddaman {
567*b30d1939SAndy Fiddaman 	reg Block_t	*b, *endb;
568*b30d1939SAndy Fiddaman 	reg Seg_t*	seg;
569*b30d1939SAndy Fiddaman 	int		rv;
570*b30d1939SAndy Fiddaman 	reg Vmdata_t*	vd = vm->data;
571*b30d1939SAndy Fiddaman 
572*b30d1939SAndy Fiddaman 	/* check the meta-data of this region */
573*b30d1939SAndy Fiddaman 	if(vd->mode & (VM_MTDEBUG|VM_MTBEST|VM_MTPROFILE))
574*b30d1939SAndy Fiddaman 	{	if(_vmbestcheck(vd, NIL(Block_t*)) < 0)
575*b30d1939SAndy Fiddaman 			return -1;
576*b30d1939SAndy Fiddaman 		if(!(vd->mode&VM_MTDEBUG) )
577*b30d1939SAndy Fiddaman 			return 0;
578*b30d1939SAndy Fiddaman 	}
579*b30d1939SAndy Fiddaman 	else	return -1;
580*b30d1939SAndy Fiddaman 
581*b30d1939SAndy Fiddaman 	rv = 0;
582*b30d1939SAndy Fiddaman 	for(seg = vd->seg; seg; seg = seg->next)
583*b30d1939SAndy Fiddaman 	{	b = SEGBLOCK(seg);
584*b30d1939SAndy Fiddaman 		endb = (Block_t*)(seg->baddr - sizeof(Head_t));
585*b30d1939SAndy Fiddaman 		while(b < endb)
586*b30d1939SAndy Fiddaman 		{	reg Vmuchar_t	*data, *begp, *endp;
587*b30d1939SAndy Fiddaman 
588*b30d1939SAndy Fiddaman 			if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
589*b30d1939SAndy Fiddaman 				goto next;
590*b30d1939SAndy Fiddaman 
591*b30d1939SAndy Fiddaman 			data = DB2DEBUG(DATA(b));
592*b30d1939SAndy Fiddaman 			if(DBISBAD(data))	/* seen this before */
593*b30d1939SAndy Fiddaman 			{	rv += 1;
594*b30d1939SAndy Fiddaman 				goto next;
595*b30d1939SAndy Fiddaman 			}
596*b30d1939SAndy Fiddaman 
597*b30d1939SAndy Fiddaman 			DBHEAD(data,begp,endp);
598*b30d1939SAndy Fiddaman 			for(; begp < endp; ++begp)
599*b30d1939SAndy Fiddaman 				if(*begp != DB_MAGIC)
600*b30d1939SAndy Fiddaman 					goto set_bad;
601*b30d1939SAndy Fiddaman 
602*b30d1939SAndy Fiddaman 			DBTAIL(data,begp,endp);
603*b30d1939SAndy Fiddaman 			for(; begp < endp; ++begp)
604*b30d1939SAndy Fiddaman 			{	if(*begp == DB_MAGIC)
605*b30d1939SAndy Fiddaman 					continue;
606*b30d1939SAndy Fiddaman 			set_bad:
607*b30d1939SAndy Fiddaman 				dbwarn(vm,data,(long)(begp-data),vm->file,vm->line,0,DB_CHECK);
608*b30d1939SAndy Fiddaman 				DBSETBAD(data);
609*b30d1939SAndy Fiddaman 				rv += 1;
610*b30d1939SAndy Fiddaman 				goto next;
611*b30d1939SAndy Fiddaman 			}
612*b30d1939SAndy Fiddaman 
613*b30d1939SAndy Fiddaman 		next:	b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS));
614*b30d1939SAndy Fiddaman 		}
615*b30d1939SAndy Fiddaman 	}
616*b30d1939SAndy Fiddaman 
617*b30d1939SAndy Fiddaman 	return rv;
618*b30d1939SAndy Fiddaman }
619*b30d1939SAndy Fiddaman 
620*b30d1939SAndy Fiddaman /* set/delete an address to watch */
621*b30d1939SAndy Fiddaman #if __STD_C
vmdbwatch(Void_t * addr)622*b30d1939SAndy Fiddaman Void_t* vmdbwatch(Void_t* addr)
623*b30d1939SAndy Fiddaman #else
624*b30d1939SAndy Fiddaman Void_t* vmdbwatch(addr)
625*b30d1939SAndy Fiddaman Void_t*		addr;	/* address to insert	*/
626*b30d1939SAndy Fiddaman #endif
627*b30d1939SAndy Fiddaman {
628*b30d1939SAndy Fiddaman 	reg int		n;
629*b30d1939SAndy Fiddaman 	reg Void_t*	out;
630*b30d1939SAndy Fiddaman 
631*b30d1939SAndy Fiddaman 	out = NIL(Void_t*);
632*b30d1939SAndy Fiddaman 	if(!addr)
633*b30d1939SAndy Fiddaman 		Dbnwatch = 0;
634*b30d1939SAndy Fiddaman 	else
635*b30d1939SAndy Fiddaman 	{	for(n = Dbnwatch - 1; n >= 0; --n)
636*b30d1939SAndy Fiddaman 			if(Dbwatch[n] == addr)
637*b30d1939SAndy Fiddaman 				break;
638*b30d1939SAndy Fiddaman 		if(n < 0)	/* insert */
639*b30d1939SAndy Fiddaman 		{	if(Dbnwatch == S_WATCH)
640*b30d1939SAndy Fiddaman 			{	/* delete left-most */
641*b30d1939SAndy Fiddaman 				out = Dbwatch[0];
642*b30d1939SAndy Fiddaman 				Dbnwatch -= 1;
643*b30d1939SAndy Fiddaman 				for(n = 0; n < Dbnwatch; ++n)
644*b30d1939SAndy Fiddaman 					Dbwatch[n] = Dbwatch[n+1];
645*b30d1939SAndy Fiddaman 			}
646*b30d1939SAndy Fiddaman 			Dbwatch[Dbnwatch] = addr;
647*b30d1939SAndy Fiddaman 			Dbnwatch += 1;
648*b30d1939SAndy Fiddaman 		}
649*b30d1939SAndy Fiddaman 	}
650*b30d1939SAndy Fiddaman 	return out;
651*b30d1939SAndy Fiddaman }
652*b30d1939SAndy Fiddaman 
653*b30d1939SAndy Fiddaman #if __STD_C
dbalign(Vmalloc_t * vm,size_t size,size_t align,int local)654*b30d1939SAndy Fiddaman static Void_t* dbalign(Vmalloc_t* vm, size_t size, size_t align, int local)
655*b30d1939SAndy Fiddaman #else
656*b30d1939SAndy Fiddaman static Void_t* dbalign(vm, size, align, local)
657*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
658*b30d1939SAndy Fiddaman size_t		size;
659*b30d1939SAndy Fiddaman size_t		align;
660*b30d1939SAndy Fiddaman int		local;
661*b30d1939SAndy Fiddaman #endif
662*b30d1939SAndy Fiddaman {
663*b30d1939SAndy Fiddaman 	Vmuchar_t	*data;
664*b30d1939SAndy Fiddaman 	size_t		s;
665*b30d1939SAndy Fiddaman 	char		*file;
666*b30d1939SAndy Fiddaman 	int		line;
667*b30d1939SAndy Fiddaman 	Void_t		*func;
668*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
669*b30d1939SAndy Fiddaman 	VMFLF(vm,file,line,func);
670*b30d1939SAndy Fiddaman 
671*b30d1939SAndy Fiddaman 	if(size <= 0 || align <= 0)
672*b30d1939SAndy Fiddaman 		return NIL(Void_t*);
673*b30d1939SAndy Fiddaman 
674*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
675*b30d1939SAndy Fiddaman 
676*b30d1939SAndy Fiddaman 	if((s = ROUND(size,ALIGN) + DB_EXTRA) < sizeof(Body_t))
677*b30d1939SAndy Fiddaman 		s = sizeof(Body_t);
678*b30d1939SAndy Fiddaman 
679*b30d1939SAndy Fiddaman 	if((data = (Vmuchar_t*)KPVALIGN(vm,s,align,(*(Vmbest->alignf)))) )
680*b30d1939SAndy Fiddaman 	{	data += DB_HEAD;
681*b30d1939SAndy Fiddaman 		dbsetinfo(data,size,file,line);
682*b30d1939SAndy Fiddaman 
683*b30d1939SAndy Fiddaman 		if((vd->mode&VM_TRACE) && _Vmtrace)
684*b30d1939SAndy Fiddaman 		{	vm->file = file; vm->line = line; vm->func = func;
685*b30d1939SAndy Fiddaman 			(*_Vmtrace)(vm,NIL(Vmuchar_t*),data,size,align);
686*b30d1939SAndy Fiddaman 		}
687*b30d1939SAndy Fiddaman 	}
688*b30d1939SAndy Fiddaman 
689*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
690*b30d1939SAndy Fiddaman 
691*b30d1939SAndy Fiddaman 	return (Void_t*)data;
692*b30d1939SAndy Fiddaman }
693*b30d1939SAndy Fiddaman 
694*b30d1939SAndy Fiddaman /* print statistics of region vm. If vm is NULL, use Vmregion */
695*b30d1939SAndy Fiddaman #if __STD_C
vmdbstat(Vmalloc_t * vm)696*b30d1939SAndy Fiddaman ssize_t vmdbstat(Vmalloc_t* vm)
697*b30d1939SAndy Fiddaman #else
698*b30d1939SAndy Fiddaman ssize_t vmdbstat(vm)
699*b30d1939SAndy Fiddaman Vmalloc_t*	vm;
700*b30d1939SAndy Fiddaman #endif
701*b30d1939SAndy Fiddaman {	Vmstat_t	st;
702*b30d1939SAndy Fiddaman 	char		buf[1024], *bufp;
703*b30d1939SAndy Fiddaman 
704*b30d1939SAndy Fiddaman 	vmstat(vm ? vm : Vmregion, &st);
705*b30d1939SAndy Fiddaman 	bufp = buf;
706*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, "n_busy", '=');
707*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_busy),-1), ',');
708*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, " s_busy", '=');
709*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.s_busy),-1), '\n');
710*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, "n_free", '=');
711*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_free),-1), ',');
712*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, " s_free", '=');
713*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.s_free),-1), '\n');
714*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, "m_busy", '=');
715*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.m_busy),-1), ',');
716*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, " m_free", '=');
717*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.m_free),-1), '\n');
718*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, "n_segment", '=');
719*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_seg),-1), ',');
720*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, " extent", '=');
721*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.extent),-1), '\n');
722*b30d1939SAndy Fiddaman 	*bufp = 0;
723*b30d1939SAndy Fiddaman 	write(Dbfd, buf, strlen(buf));
724*b30d1939SAndy Fiddaman 	return strlen(buf);
725*b30d1939SAndy Fiddaman }
726*b30d1939SAndy Fiddaman 
727*b30d1939SAndy Fiddaman static Vmethod_t _Vmdebug =
728*b30d1939SAndy Fiddaman {
729*b30d1939SAndy Fiddaman 	dballoc,
730*b30d1939SAndy Fiddaman 	dbresize,
731*b30d1939SAndy Fiddaman 	dbfree,
732*b30d1939SAndy Fiddaman 	dbaddr,
733*b30d1939SAndy Fiddaman 	dbsize,
734*b30d1939SAndy Fiddaman 	dbcompact,
735*b30d1939SAndy Fiddaman 	dbalign,
736*b30d1939SAndy Fiddaman 	VM_MTDEBUG
737*b30d1939SAndy Fiddaman };
738*b30d1939SAndy Fiddaman 
739*b30d1939SAndy Fiddaman __DEFINE__(Vmethod_t*,Vmdebug,&_Vmdebug);
740*b30d1939SAndy Fiddaman 
741*b30d1939SAndy Fiddaman #ifdef NoF
742*b30d1939SAndy Fiddaman NoF(vmdebug)
743*b30d1939SAndy Fiddaman #endif
744*b30d1939SAndy Fiddaman 
745*b30d1939SAndy Fiddaman #endif
746