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