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