xref: /titanic_44/usr/src/lib/libast/common/vmalloc/malloc.c (revision 55f5292c612446ce6f93ddd248c0019b5974618b)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2009 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *            http://www.opensource.org/licenses/cpl1.0.txt             *
11 *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 #if defined(_UWIN) && defined(_BLD_ast)
23 
24 void _STUB_malloc(){}
25 
26 #else
27 
28 #if _UWIN
29 
30 #define calloc		______calloc
31 #define _ast_free	______free
32 #define malloc		______malloc
33 #define mallinfo	______mallinfo
34 #define mallopt		______mallopt
35 #define mstats		______mstats
36 #define realloc		______realloc
37 
38 #define _STDLIB_H_	1
39 
40 extern int		atexit(void(*)(void));
41 extern char*		getenv(const char*);
42 
43 #endif
44 
45 #include	"vmhdr.h"
46 #include	<errno.h>
47 
48 #if _UWIN
49 
50 #include	<malloc.h>
51 
52 #define _map_malloc	1
53 #define _mal_alloca	1
54 
55 #undef	calloc
56 #define calloc		_ast_calloc
57 #undef	_ast_free
58 #define free		_ast_free
59 #undef	malloc
60 #define malloc		_ast_malloc
61 #undef	mallinfo
62 typedef struct ______mallinfo Mallinfo_t;
63 #undef	mallopt
64 #undef	mstats
65 typedef struct ______mstats Mstats_t;
66 #undef	realloc
67 #define realloc		_ast_realloc
68 
69 #endif
70 
71 #if __STD_C
72 #define F0(f,t0)		f(t0)
73 #define F1(f,t1,a1)		f(t1 a1)
74 #define F2(f,t1,a1,t2,a2)	f(t1 a1, t2 a2)
75 #else
76 #define F0(f,t0)		f()
77 #define F1(f,t1,a1)		f(a1) t1 a1;
78 #define F2(f,t1,a1,t2,a2)	f(a1, a2) t1 a1; t2 a2;
79 #endif
80 
81 /*
82  * define _AST_std_malloc=1 to force the standard malloc
83  * if _map_malloc is also defined then _ast_malloc etc.
84  * will simply call malloc etc.
85  */
86 
87 #if !defined(_AST_std_malloc) && __CYGWIN__
88 #define _AST_std_malloc	1
89 #endif
90 
91 #if ( !_std_malloc || !_BLD_ast ) && !_AST_std_malloc
92 
93 /*	malloc compatibility functions.
94 **	These are aware of debugging/profiling and driven by the environment variables:
95 **	VMETHOD: select an allocation method by name.
96 **
97 **	VMPROFILE: if is a file name, write profile data to it.
98 **	VMTRACE: if is a file name, write trace data to it.
99 **	The pattern %p in a file name will be replaced by the process ID.
100 **
101 **	VMDEBUG:
102 **		a:			abort on any warning.
103 **		w[decimal]:		file descriptor for warnings.
104 **		[decimal]:		period to check arena.
105 **		0x[hexadecimal]:	address to watch.
106 **
107 **	Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
108 */
109 
110 #if _sys_stat
111 #include	<sys/stat.h>
112 #endif
113 #include	<fcntl.h>
114 
115 #ifdef S_IRUSR
116 #define CREAT_MODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
117 #else
118 #define CREAT_MODE	0644
119 #endif
120 
121 #if !_map_malloc
122 #undef calloc
123 #undef cfree
124 #undef free
125 #undef mallinfo
126 #undef malloc
127 #undef mallopt
128 #undef memalign
129 #undef mstats
130 #undef realloc
131 #undef valloc
132 #endif
133 
134 #if _WINIX
135 
136 #include <ast_windows.h>
137 
138 #if _UWIN
139 
140 #define VMRECORD(p)	_vmrecord(p)
141 #define VMBLOCK		{ int _vmblock = _sigblock();
142 #define VMUNBLOCK	_sigunblock(_vmblock); }
143 
144 extern int		_sigblock(void);
145 extern void		_sigunblock(int);
146 extern unsigned long	_record[2048];
147 
148 __inline Void_t* _vmrecord(Void_t* p)
149 {
150 	register unsigned long	v = ((unsigned long)p)>>16;
151 
152 	_record[v>>5] |= 1<<((v&0x1f));
153 	return p;
154 }
155 
156 #else
157 
158 #define getenv(s)	lcl_getenv(s)
159 
160 static char*
161 lcl_getenv(const char* s)
162 {
163 	int		n;
164 	static char	buf[512];
165 
166 	if (!(n = GetEnvironmentVariable(s, buf, sizeof(buf))) || n > sizeof(buf))
167 		return 0;
168 	return buf;
169 }
170 
171 #endif /* _UWIN */
172 
173 #endif /* _WINIX */
174 
175 #ifndef VMRECORD
176 #define VMRECORD(p)	(p)
177 #define VMBLOCK
178 #define VMUNBLOCK
179 #endif
180 
181 #if defined(__EXPORT__)
182 #define extern		extern __EXPORT__
183 #endif
184 
185 #if __STD_C
186 static Vmulong_t atou(char** sp)
187 #else
188 static Vmulong_t atou(sp)
189 char**	sp;
190 #endif
191 {
192 	char*		s = *sp;
193 	Vmulong_t	v = 0;
194 
195 	if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X') )
196 	{	for(s += 2; *s; ++s)
197 		{	if(*s >= '0' && *s <= '9')
198 				v = (v << 4) + (*s - '0');
199 			else if(*s >= 'a' && *s <= 'f')
200 				v = (v << 4) + (*s - 'a') + 10;
201 			else if(*s >= 'A' && *s <= 'F')
202 				v = (v << 4) + (*s - 'A') + 10;
203 			else break;
204 		}
205 	}
206 	else
207 	{	for(; *s; ++s)
208 		{	if(*s >= '0' && *s <= '9')
209 				v = v*10 + (*s - '0');
210 			else break;
211 		}
212 	}
213 
214 	*sp = s;
215 	return v;
216 }
217 
218 static int		_Vmflinit = 0;
219 static Vmulong_t	_Vmdbstart = 0;
220 static Vmulong_t	_Vmdbcheck = 0;
221 static Vmulong_t	_Vmdbtime = 0;
222 static int		_Vmpffd = -1;
223 #define VMFLINIT() \
224 	{ if(!_Vmflinit)	vmflinit(); \
225 	  if(_Vmdbcheck) \
226 	  { if(_Vmdbtime < _Vmdbstart) _Vmdbtime += 1; \
227 	    else if((_Vmdbtime += 1) < _Vmdbstart) _Vmdbtime = _Vmdbstart; \
228 	    if(_Vmdbtime >= _Vmdbstart && (_Vmdbtime % _Vmdbcheck) == 0 && \
229 	       Vmregion->meth.meth == VM_MTDEBUG) \
230 		vmdbcheck(Vmregion); \
231 	  } \
232 	}
233 
234 #if __STD_C
235 static char* insertpid(char* begs, char* ends)
236 #else
237 static char* insertpid(begs,ends)
238 char*	begs;
239 char*	ends;
240 #endif
241 {	int	pid;
242 	char*	s;
243 
244 	if((pid = getpid()) < 0)
245 		return NIL(char*);
246 
247 	s = ends;
248 	do
249 	{	if(s == begs)
250 			return NIL(char*);
251 		*--s = '0' + pid%10;
252 	} while((pid /= 10) > 0);
253 	while(s < ends)
254 		*begs++ = *s++;
255 
256 	return begs;
257 }
258 
259 #if __STD_C
260 static int createfile(char* file)
261 #else
262 static int createfile(file)
263 char*	file;
264 #endif
265 {
266 	char	buf[1024];
267 	char	*next, *endb;
268 
269 	next = buf;
270 	endb = buf + sizeof(buf);
271 	while(*file)
272 	{	if(*file == '%')
273 		{	switch(file[1])
274 			{
275 			case 'p' :
276 				if(!(next = insertpid(next,endb)) )
277 					return -1;
278 				file += 2;
279 				break;
280 			default :
281 				goto copy;
282 			}
283 		}
284 		else
285 		{ copy:
286 			*next++ = *file++;
287 		}
288 
289 		if(next >= endb)
290 			return -1;
291 	}
292 
293 	*next = '\0';
294 #if _PACKAGE_ast
295 	{	int	fd;
296 		fd = open(buf,O_WRONLY|O_CREAT|O_TRUNC,CREAT_MODE);
297 #ifdef FD_CLOEXEC
298 		if (fd >= 0)
299 			fcntl(fd, F_SETFD, FD_CLOEXEC);
300 #endif
301 		return fd;
302 	}
303 #else
304 	return creat(buf,CREAT_MODE);
305 #endif
306 }
307 
308 #if __STD_C
309 static void pfprint(void)
310 #else
311 static void pfprint()
312 #endif
313 {
314 	if(Vmregion->meth.meth == VM_MTPROFILE)
315 		vmprofile(Vmregion,_Vmpffd);
316 }
317 
318 #if __STD_C
319 static int vmflinit(void)
320 #else
321 static int vmflinit()
322 #endif
323 {
324 	char*		env;
325 	Vmalloc_t*	vm;
326 	int		fd;
327 	Vmulong_t	addr;
328 	char*		file;
329 	int		line;
330 	Void_t*		func;
331 
332 	/* this must be done now to avoid any inadvertent recursion (more below) */
333 	_Vmflinit = 1;
334 	VMFLF(Vmregion,file,line,func);
335 
336 	/* if getenv() calls malloc(), the eventual region may not see this */
337 	vm = NIL(Vmalloc_t*);
338 	if((env = getenv("VMETHOD")) )
339 	{	if(strcmp(env,"Vmdebug") == 0 || strcmp(env,"vmdebug") == 0)
340 			vm = vmopen(Vmdcsbrk,Vmdebug,0);
341 		else if(strcmp(env,"Vmprofile") == 0 || strcmp(env,"vmprofile") == 0 )
342 			vm = vmopen(Vmdcsbrk,Vmprofile,0);
343 		else if(strcmp(env,"Vmlast") == 0 || strcmp(env,"vmlast") == 0 )
344 			vm = vmopen(Vmdcsbrk,Vmlast,0);
345 		else if(strcmp(env,"Vmbest") == 0 || strcmp(env,"vmbest") == 0 )
346 			vm = Vmheap;
347 	}
348 
349 	if((!vm || vm->meth.meth == VM_MTDEBUG) &&
350 	   (env = getenv("VMDEBUG")) && env[0] )
351 	{	if(vm || (vm = vmopen(Vmdcsbrk,Vmdebug,0)) )
352 		{	reg int	setcheck = 0;
353 
354 			while(*env)
355 			{	if(*env == 'a')
356 				{	vmset(vm,VM_DBABORT,1);
357 					env += 1;
358 				}
359 				else if(*env =='w')
360 				{	env += 1;
361 					if((fd = atou(&env)) >= 0 )
362 						vmdebug(fd);
363 				}
364 				else if(*env < '0' || *env > '9')
365 					env += 1;
366 				else if(env[0] == '0' && (env[1] == 'x' || env[1] == 'X') )
367 				{	if((addr = atou(&env)) != 0)
368 						vmdbwatch((Void_t*)addr);
369 				}
370 				else
371 				{	_Vmdbcheck = atou(&env);
372 					setcheck = 1;
373 					if(*env == ',')
374 					{	env += 1;
375 						_Vmdbstart = atou(&env);
376 					}
377 				}
378 			}
379 			if(!setcheck)
380 				_Vmdbcheck = 1;
381 		}
382 	}
383 
384 	if((!vm || vm->meth.meth == VM_MTPROFILE) &&
385 	   (env = getenv("VMPROFILE")) && env[0] )
386 	{	_Vmpffd = createfile(env);
387 		if(!vm)
388 			vm = vmopen(Vmdcsbrk,Vmprofile,0);
389 	}
390 
391 	/* slip in the new region now so that malloc() will work fine */
392 	if(vm)
393 		Vmregion = vm;
394 
395 	/* turn on tracing if requested */
396 	if((env = getenv("VMTRACE")) && env[0] && (fd = createfile(env)) >= 0)
397 	{	vmset(Vmregion,VM_TRACE,1);
398 		vmtrace(fd);
399 	}
400 
401 	/* make sure that profile data is output upon exiting */
402 	if(vm && vm->meth.meth == VM_MTPROFILE)
403 	{	if(_Vmpffd < 0)
404 			_Vmpffd = 2;
405 		/* this may wind up calling malloc(), but region is ok now */
406 		atexit(pfprint);
407 	}
408 	else if(_Vmpffd >= 0)
409 	{	close(_Vmpffd);
410 		_Vmpffd = -1;
411 	}
412 
413 	/* reset file and line number to correct values for the call */
414 	Vmregion->file = file;
415 	Vmregion->line = line;
416 	Vmregion->func = func;
417 
418 	return 0;
419 }
420 
421 #if __STD_C
422 extern Void_t* calloc(reg size_t n_obj, reg size_t s_obj)
423 #else
424 extern Void_t* calloc(n_obj, s_obj)
425 reg size_t	n_obj;
426 reg size_t	s_obj;
427 #endif
428 {
429 	VMFLINIT();
430 	return VMRECORD((*Vmregion->meth.resizef)(Vmregion,NIL(Void_t*),n_obj*s_obj,VM_RSZERO));
431 }
432 
433 #if __STD_C
434 extern Void_t* malloc(reg size_t size)
435 #else
436 extern Void_t* malloc(size)
437 reg size_t	size;
438 #endif
439 {
440 	VMFLINIT();
441 	return VMRECORD((*Vmregion->meth.allocf)(Vmregion,size));
442 }
443 
444 #if __STD_C
445 extern Void_t* realloc(reg Void_t* data, reg size_t size)
446 #else
447 extern Void_t* realloc(data,size)
448 reg Void_t*	data;	/* block to be reallocated	*/
449 reg size_t	size;	/* new size			*/
450 #endif
451 {
452 #if USE_NATIVE
453 #undef	realloc
454 #if __STD_C
455 	extern Void_t*	realloc(Void_t*, size_t);
456 #else
457 	extern Void_t*	realloc();
458 #endif
459 #endif
460 
461 	VMFLINIT();
462 
463 #if _PACKAGE_ast
464 	if(data && Vmregion->meth.meth != VM_MTDEBUG &&
465 #if !USE_NATIVE
466 	   !(Vmregion->data->mode&VM_TRUST) &&
467 #endif
468 	   (*Vmregion->meth.addrf)(Vmregion,data) != 0 )
469 	{
470 #if USE_NATIVE
471 		return realloc(data, size);
472 #else
473 		Void_t*	newdata;
474 		if((newdata = (*Vmregion->meth.allocf)(Vmregion,size)) )
475 			memcpy(newdata,data,size);
476 		return VMRECORD(newdata);
477 #endif
478 	}
479 #endif
480 
481 #if USE_NATIVE
482 	{	Void_t*	newdata;
483 		if (newdata = (*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE))
484 			return newdata;
485 		return VMRECORD(realloc(data, size));
486 	}
487 #else
488 	return VMRECORD((*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE));
489 #endif
490 }
491 
492 #if __STD_C
493 extern void free(reg Void_t* data)
494 #else
495 extern void free(data)
496 reg Void_t*	data;
497 #endif
498 {
499 #if USE_NATIVE
500 #undef	free
501 #if __STD_C
502 	extern void	free(Void_t*);
503 #else
504 	extern void	free();
505 #endif
506 #endif
507 
508 	VMFLINIT();
509 
510 #if _PACKAGE_ast
511 	if(data && Vmregion->meth.meth != VM_MTDEBUG &&
512 #if !USE_NATIVE
513 	   !(Vmregion->data->mode&VM_TRUST) &&
514 #endif
515 	   (*Vmregion->meth.addrf)(Vmregion,data) != 0)
516 	{
517 #if USE_NATIVE
518 		free(data);
519 #endif
520 		return;
521 	}
522 #endif
523 
524 #if USE_NATIVE
525 	if ((*Vmregion->meth.freef)(Vmregion,data) != 0)
526 		free(data);
527 #else
528 	(void)(*Vmregion->meth.freef)(Vmregion,data);
529 #endif
530 }
531 
532 #if __STD_C
533 extern void cfree(reg Void_t* data)
534 #else
535 extern void cfree(data)
536 reg Void_t*	data;
537 #endif
538 {
539 	free(data);
540 }
541 
542 #if __STD_C
543 extern Void_t* memalign(reg size_t align, reg size_t size)
544 #else
545 extern Void_t* memalign(align, size)
546 reg size_t	align;
547 reg size_t	size;
548 #endif
549 {
550 	Void_t*	addr;
551 
552 	VMFLINIT();
553 	VMBLOCK
554 	addr = VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,align));
555 	VMUNBLOCK
556 	return addr;
557 }
558 
559 #if __STD_C
560 extern int posix_memalign(reg Void_t **memptr, reg size_t align, reg size_t size)
561 #else
562 extern int posix_memalign(memptr, align, size)
563 reg Void_t**	memptr;
564 reg size_t	align;
565 reg size_t	size;
566 #endif
567 {
568 	Void_t	*mem;
569 
570 	if(align == 0 || (align%sizeof(Void_t*)) != 0 || ((align-1)&align) != 0 )
571 		return EINVAL;
572 
573 	if(!(mem = memalign(align, size)) )
574 		return ENOMEM;
575 
576 	*memptr = mem;
577 	return 0;
578 }
579 
580 #if __STD_C
581 extern Void_t* valloc(reg size_t size)
582 #else
583 extern Void_t* valloc(size)
584 reg size_t	size;
585 #endif
586 {
587 	VMFLINIT();
588 	GETPAGESIZE(_Vmpagesize);
589 	return VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,_Vmpagesize));
590 }
591 
592 #if __STD_C
593 extern Void_t* pvalloc(reg size_t size)
594 #else
595 extern Void_t* pvalloc(size)
596 reg size_t	size;
597 #endif
598 {
599 	VMFLINIT();
600 	GETPAGESIZE(_Vmpagesize);
601 	return VMRECORD((*Vmregion->meth.alignf)(Vmregion,ROUND(size,_Vmpagesize),_Vmpagesize));
602 }
603 
604 #if !_PACKAGE_ast
605 #if __STD_C
606 char* strdup(const char* s)
607 #else
608 char* strdup(s)
609 char*	s;
610 #endif
611 {
612 	char	*ns;
613 	size_t	n;
614 
615 	if(!s)
616 		return NIL(char*);
617 	else
618 	{	n = strlen(s);
619 		if((ns = malloc(n+1)) )
620 			memcpy(ns,s,n+1);
621 		return ns;
622 	}
623 }
624 #endif /* _PACKAGE_ast */
625 
626 #if !_lib_alloca || _mal_alloca
627 #ifndef _stk_down
628 #define _stk_down	0
629 #endif
630 typedef struct _alloca_s	Alloca_t;
631 union _alloca_u
632 {	struct
633 	{	char*		addr;
634 		Alloca_t*	next;
635 	} head;
636 	char	array[ALIGN];
637 };
638 struct _alloca_s
639 {	union _alloca_u	head;
640 	Vmuchar_t	data[1];
641 };
642 
643 #if __STD_C
644 extern Void_t* alloca(size_t size)
645 #else
646 extern Void_t* alloca(size)
647 size_t	size;
648 #endif
649 {	char		array[ALIGN];
650 	char*		file;
651 	int		line;
652 	Void_t*		func;
653 	reg Alloca_t*	f;
654 	static Alloca_t* Frame;
655 
656 	VMFLINIT();
657 	VMFLF(Vmregion,file,line,func);
658 	while(Frame)
659 	{	if(( _stk_down && &array[0] > Frame->head.head.addr) ||
660 		   (!_stk_down && &array[0] < Frame->head.head.addr) )
661 		{	f = Frame;
662 			Frame = f->head.head.next;
663 			(void)(*Vmregion->meth.freef)(Vmregion,f);
664 		}
665 		else	break;
666 	}
667 
668 	Vmregion->file = file;
669 	Vmregion->line = line;
670 	Vmregion->func = func;
671 	f = (Alloca_t*)(*Vmregion->meth.allocf)(Vmregion,size+sizeof(Alloca_t)-1);
672 
673 	f->head.head.addr = &array[0];
674 	f->head.head.next = Frame;
675 	Frame = f;
676 
677 	return (Void_t*)f->data;
678 }
679 #endif /*!_lib_alloca || _mal_alloca*/
680 
681 #if _map_malloc
682 
683 /* not sure of all the implications -- 0 is conservative for now */
684 #define USE_NATIVE	0	/* native free/realloc on non-vmalloc ptrs */
685 
686 #else
687 
688 /* intercept _* __* __libc_* variants */
689 
690 #if __lib__malloc
691 extern Void_t*	F2(_calloc, size_t,n, size_t,m) { return calloc(n, m); }
692 extern Void_t	F1(_cfree, Void_t*,p) { free(p); }
693 extern Void_t	F1(_free, Void_t*,p) { free(p); }
694 extern Void_t*	F1(_malloc, size_t,n) { return malloc(n); }
695 #if _lib_memalign
696 extern Void_t*	F2(_memalign, size_t,a, size_t,n) { return memalign(a, n); }
697 #endif
698 #if _lib_pvalloc
699 extern Void_t*	F1(_pvalloc, size_t,n) { return pvalloc(n); }
700 #endif
701 extern Void_t*	F2(_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
702 #if _lib_valloc
703 extern Void_t*	F1(_valloc, size_t,n) { return valloc(n); }
704 #endif
705 #endif
706 
707 #if _lib___malloc
708 extern Void_t*	F2(__calloc, size_t,n, size_t,m) { return calloc(n, m); }
709 extern Void_t	F1(__cfree, Void_t*,p) { free(p); }
710 extern Void_t	F1(__free, Void_t*,p) { free(p); }
711 extern Void_t*	F1(__malloc, size_t,n) { return malloc(n); }
712 #if _lib_memalign
713 extern Void_t*	F2(__memalign, size_t,a, size_t,n) { return memalign(a, n); }
714 #endif
715 #if _lib_pvalloc
716 extern Void_t*	F1(__pvalloc, size_t,n) { return pvalloc(n); }
717 #endif
718 extern Void_t*	F2(__realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
719 #if _lib_valloc
720 extern Void_t*	F1(__valloc, size_t,n) { return valloc(n); }
721 #endif
722 #endif
723 
724 #if _lib___libc_malloc
725 extern Void_t*	F2(__libc_calloc, size_t,n, size_t,m) { return calloc(n, m); }
726 extern Void_t	F1(__libc_cfree, Void_t*,p) { free(p); }
727 extern Void_t	F1(__libc_free, Void_t*,p) { free(p); }
728 extern Void_t*	F1(__libc_malloc, size_t,n) { return malloc(n); }
729 #if _lib_memalign
730 extern Void_t*	F2(__libc_memalign, size_t,a, size_t,n) { return memalign(a, n); }
731 #endif
732 #if _lib_pvalloc
733 extern Void_t*	F1(__libc_pvalloc, size_t,n) { return pvalloc(n); }
734 #endif
735 extern Void_t*	F2(__libc_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
736 #if _lib_valloc
737 extern Void_t*	F1(__libc_valloc, size_t,n) { return valloc(n); }
738 #endif
739 #endif
740 
741 #endif /* _map_malloc */
742 
743 #undef	extern
744 
745 #if _hdr_malloc /* need the mallint interface for statistics, etc. */
746 
747 #undef	calloc
748 #define calloc		______calloc
749 #undef	cfree
750 #define cfree		______cfree
751 #undef	free
752 #define free		______free
753 #undef	malloc
754 #define malloc		______malloc
755 #undef	pvalloc
756 #define pvalloc		______pvalloc
757 #undef	realloc
758 #define realloc		______realloc
759 #undef	valloc
760 #define valloc		______valloc
761 
762 #if !_UWIN
763 
764 #include	<malloc.h>
765 
766 typedef struct mallinfo Mallinfo_t;
767 typedef struct mstats Mstats_t;
768 
769 #endif
770 
771 #if defined(__EXPORT__)
772 #define extern		__EXPORT__
773 #endif
774 
775 #if _lib_mallopt
776 #if __STD_C
777 extern int mallopt(int cmd, int value)
778 #else
779 extern int mallopt(cmd, value)
780 int	cmd;
781 int	value;
782 #endif
783 {
784 	VMFLINIT();
785 	return 0;
786 }
787 #endif /*_lib_mallopt*/
788 
789 #if _lib_mallinfo && _mem_arena_mallinfo
790 #if __STD_C
791 extern Mallinfo_t mallinfo(void)
792 #else
793 extern Mallinfo_t mallinfo()
794 #endif
795 {
796 	Vmstat_t	sb;
797 	Mallinfo_t	mi;
798 
799 	VMFLINIT();
800 	memset(&mi,0,sizeof(mi));
801 	if(vmstat(Vmregion,&sb) >= 0)
802 	{	mi.arena = sb.extent;
803 		mi.ordblks = sb.n_busy+sb.n_free;
804 		mi.uordblks = sb.s_busy;
805 		mi.fordblks = sb.s_free;
806 	}
807 	return mi;
808 }
809 #endif /* _lib_mallinfo */
810 
811 #if _lib_mstats && _mem_bytes_total_mstats
812 #if __STD_C
813 extern Mstats_t mstats(void)
814 #else
815 extern Mstats_t mstats()
816 #endif
817 {
818 	Vmstat_t	sb;
819 	Mstats_t	ms;
820 
821 	VMFLINIT();
822 	memset(&ms,0,sizeof(ms));
823 	if(vmstat(Vmregion,&sb) >= 0)
824 	{	ms.bytes_total = sb.extent;
825 		ms.chunks_used = sb.n_busy;
826 		ms.bytes_used = sb.s_busy;
827 		ms.chunks_free = sb.n_free;
828 		ms.bytes_free = sb.s_free;
829 	}
830 	return ms;
831 }
832 #endif /*_lib_mstats*/
833 
834 #undef	extern
835 
836 #endif/*_hdr_malloc*/
837 
838 #else
839 
840 /*
841  * even though there is no malloc override, still provide
842  * _ast_* counterparts for object compatibility
843  */
844 
845 #undef	calloc
846 extern Void_t*	calloc _ARG_((size_t, size_t));
847 
848 #undef	cfree
849 extern void	cfree _ARG_((Void_t*));
850 
851 #undef	free
852 extern void	free _ARG_((Void_t*));
853 
854 #undef	malloc
855 extern Void_t*	malloc _ARG_((size_t));
856 
857 #if _lib_memalign
858 #undef	memalign
859 extern Void_t*	memalign _ARG_((size_t, size_t));
860 #endif
861 
862 #if _lib_pvalloc
863 #undef	pvalloc
864 extern Void_t*	pvalloc _ARG_((size_t));
865 #endif
866 
867 #undef	realloc
868 extern Void_t*	realloc _ARG_((Void_t*, size_t));
869 
870 #if _lib_valloc
871 #undef	valloc
872 extern Void_t*	valloc _ARG_((size_t));
873 #endif
874 
875 #if defined(__EXPORT__)
876 #define extern		__EXPORT__
877 #endif
878 
879 extern Void_t*	F2(_ast_calloc, size_t,n, size_t,m) { return calloc(n, m); }
880 extern Void_t	F1(_ast_cfree, Void_t*,p) { free(p); }
881 extern Void_t	F1(_ast_free, Void_t*,p) { free(p); }
882 extern Void_t*	F1(_ast_malloc, size_t,n) { return malloc(n); }
883 #if _lib_memalign
884 extern Void_t*	F2(_ast_memalign, size_t,a, size_t,n) { return memalign(a, n); }
885 #endif
886 #if _lib_pvalloc
887 extern Void_t*	F1(_ast_pvalloc, size_t,n) { return pvalloc(n); }
888 #endif
889 extern Void_t*	F2(_ast_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
890 #if _lib_valloc
891 extern Void_t*	F1(_ast_valloc, size_t,n) { return valloc(n); }
892 #endif
893 
894 #undef	extern
895 
896 #if _hdr_malloc
897 
898 #undef	mallinfo
899 #undef	mallopt
900 #undef	mstats
901 
902 #define calloc		______calloc
903 #define cfree		______cfree
904 #define free		______free
905 #define malloc		______malloc
906 #define pvalloc		______pvalloc
907 #define realloc		______realloc
908 #define valloc		______valloc
909 
910 #if !_UWIN
911 
912 #include	<malloc.h>
913 
914 typedef struct mallinfo Mallinfo_t;
915 typedef struct mstats Mstats_t;
916 
917 #endif
918 
919 #if defined(__EXPORT__)
920 #define extern		__EXPORT__
921 #endif
922 
923 #if _lib_mallopt
924 extern int	F2(_ast_mallopt, int,cmd, int,value) { return mallopt(cmd, value); }
925 #endif
926 
927 #if _lib_mallinfo && _mem_arena_mallinfo
928 extern Mallinfo_t	F0(_ast_mallinfo, void) { return mallinfo(); }
929 #endif
930 
931 #if _lib_mstats && _mem_bytes_total_mstats
932 extern Mstats_t		F0(_ast_mstats, void) { return mstats(); }
933 #endif
934 
935 #undef	extern
936 
937 #endif /*_hdr_malloc*/
938 
939 #endif /*!_std_malloc*/
940 
941 #endif /*_UWIN*/
942