3
#if _std_malloc || _BLD_INSTRUMENT_ || cray
7
/* malloc compatibility functions.
8
** These are aware of debugging/profiling and driven by the environment variables:
9
** VMETHOD: select an allocation method by name.
11
** VMPROFILE: if is a file name, write profile data to it.
12
** VMTRACE: if is a file name, write trace data to it.
13
** The pattern %p in a file name will be replaced by the process ID.
16
** a: abort on any warning
17
** [decimal]: period to check arena.
18
** 0x[hexadecimal]: address to watch.
20
** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
32
#define CREAT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
34
#define CREAT_MODE 0644
46
static Vmulong_t atou(char** sp)
48
static Vmulong_t atou(sp)
55
if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X') )
56
{ for(s += 2; *s; ++s)
57
{ if(*s >= '0' && *s <= '9')
58
v = (v << 4) + (*s - '0');
59
else if(*s >= 'a' && *s <= 'f')
60
v = (v << 4) + (*s - 'a') + 10;
61
else if(*s >= 'A' && *s <= 'F')
62
v = (v << 4) + (*s - 'A') + 10;
68
{ if(*s >= '0' && *s <= '9')
69
v = v*10 + (*s - '0');
78
static int _Vmflinit = 0;
79
static Vmulong_t _Vmdbcheck = 0;
80
static Vmulong_t _Vmdbtime = 0;
81
static int _Vmpffd = -1;
83
{ if(!_Vmflinit) vmflinit(); \
84
if(_Vmdbcheck && (++_Vmdbtime % _Vmdbcheck) == 0 && \
85
Vmregion->meth.meth == VM_MTDEBUG) \
86
vmdbcheck(Vmregion); \
90
static char* insertpid(char* begs, char* ends)
92
static char* insertpid(begs,ends)
99
if((pid = getpid()) < 0)
107
} while((pid /= 10) > 0);
115
static int createfile(char* file)
117
static int createfile(file)
125
endb = buf + sizeof(buf);
131
if(!(next = insertpid(next,endb)) )
150
return open(buf,O_WRONLY|O_CREAT|O_TRUNC,CREAT_MODE);
152
return creat(buf,CREAT_MODE);
157
static void pfprint(void)
159
static void pfprint()
162
if(Vmregion->meth.meth == VM_MTPROFILE)
163
vmprofile(Vmregion,_Vmpffd);
167
static int vmflinit(void)
169
static int vmflinit()
179
/* this must be done now to avoid any inadvertent recursion (more below) */
181
VMFILELINE(Vmregion,file,line);
183
/* if getenv() calls malloc(), this may not be caught by the eventual region */
184
vm = NIL(Vmalloc_t*);
185
if((env = getenv("VMETHOD")) )
186
{ if(strcmp(env,"Vmdebug") == 0 || strcmp(env,"vmdebug") == 0)
187
vm = vmopen(Vmdcsbrk,Vmdebug,0);
188
else if(strcmp(env,"Vmprofile") == 0 || strcmp(env,"vmprofile") == 0 )
189
vm = vmopen(Vmdcsbrk,Vmprofile,0);
190
else if(strcmp(env,"Vmlast") == 0 || strcmp(env,"vmlast") == 0 )
191
vm = vmopen(Vmdcsbrk,Vmlast,0);
192
else if(strcmp(env,"Vmpool") == 0 || strcmp(env,"vmpool") == 0 )
193
vm = vmopen(Vmdcsbrk,Vmpool,0);
194
else if(strcmp(env,"Vmbest") == 0 || strcmp(env,"vmbest") == 0 )
198
if((!vm || vm->meth.meth == VM_MTDEBUG) &&
199
(env = getenv("VMDEBUG")) && env[0] )
200
{ if(vm || (vm = vmopen(Vmdcsbrk,Vmdebug,0)) )
201
{ reg int setcheck = 0;
205
vmset(vm,VM_DBABORT,1);
207
if(*env < '0' || *env > '9')
209
else if(env[0] == '0' &&
210
(env[1] == 'x' || env[1] == 'X') )
211
{ if((addr = atou(&env)) != 0)
212
vmdbwatch((Void_t*)addr);
215
{ _Vmdbcheck = atou(&env);
224
if((!vm || vm->meth.meth == VM_MTPROFILE) &&
225
(env = getenv("VMPROFILE")) && env[0] )
226
{ _Vmpffd = createfile(env);
228
vm = vmopen(Vmdcsbrk,Vmprofile,0);
231
/* slip in the new region now so that malloc() will work fine */
235
/* turn on tracing if requested */
236
if((env = getenv("VMTRACE")) && env[0] && (fd = createfile(env)) >= 0)
237
{ vmset(Vmregion,VM_TRACE,1);
241
/* make sure that profile data is output upon exiting */
242
if(vm && vm->meth.meth == VM_MTPROFILE)
245
/* this may wind up calling malloc(), but region is ok now */
248
else if(_Vmpffd >= 0)
253
/* reset file and line number to correct values for the call */
254
Vmregion->file = file;
255
Vmregion->line = line;
261
Void_t* malloc(reg size_t size)
268
return (*Vmregion->meth.allocf)(Vmregion,size);
272
Void_t* realloc(reg Void_t* data, reg size_t size)
274
Void_t* realloc(data,size)
275
reg Void_t* data; /* block to be reallocated */
276
reg size_t size; /* new size */
280
return (*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE);
284
void free(reg Void_t* data)
291
(void)(*Vmregion->meth.freef)(Vmregion,data);
295
Void_t* calloc(reg size_t n_obj, reg size_t s_obj)
297
Void_t* calloc(n_obj, s_obj)
303
return (*Vmregion->meth.resizef)(Vmregion,NIL(Void_t*),n_obj*s_obj,VM_RSZERO);
307
void cfree(reg Void_t* data)
314
(void)(*Vmregion->meth.freef)(Vmregion,data);
318
Void_t* memalign(reg size_t align, reg size_t size)
320
Void_t* memalign(align, size)
326
return (*Vmregion->meth.alignf)(Vmregion,size,align);
330
Void_t* valloc(reg size_t size)
337
GETPAGESIZE(_Vmpagesize);
338
return (*Vmregion->meth.alignf)(Vmregion,size,_Vmpagesize);
343
#define calloc ______calloc
344
#define free ______free
345
#define malloc ______malloc
346
#define realloc ______realloc
352
int mallopt(int cmd, int value)
354
int mallopt(cmd, value)
366
struct mallinfo mallinfo(void)
368
struct mallinfo mallinfo()
375
memset(&mi,0,sizeof(mi));
376
if(vmstat(Vmregion,&sb) >= 0)
377
{ mi.arena = sb.extent;
378
mi.ordblks = sb.n_busy+sb.n_free;
379
mi.uordblks = sb.s_busy;
380
mi.fordblks = sb.s_free;
388
struct mstats mstats(void)
390
struct mstats mstats()
397
memset(&ms,0,sizeof(ms));
398
if(vmstat(Vmregion,&sb) >= 0)
399
{ ms.bytes_total = sb.extent;
400
ms.chunks_used = sb.n_busy;
401
ms.bytes_used = sb.s_busy;
402
ms.chunks_free = sb.n_free;
403
ms.bytes_free = sb.s_free;
409
#endif/*_hdr_malloc*/
411
#if !_lib_alloca || _mal_alloca
415
typedef struct _alloca_s Alloca_t;
424
{ union _alloca_u head;
429
Void_t* alloca(size_t size)
438
static Alloca_t* Frame;
441
VMFILELINE(Vmregion,file,line);
443
{ if(( _stk_down && &array[0] > Frame->head.head.addr) ||
444
(!_stk_down && &array[0] < Frame->head.head.addr) )
446
Frame = f->head.head.next;
447
(void)(*Vmregion->meth.freef)(Vmregion,f);
452
Vmregion->file = file;
453
Vmregion->line = line;
454
f = (Alloca_t*)(*Vmregion->meth.allocf)(Vmregion,size+sizeof(Alloca_t)-1);
456
f->head.head.addr = &array[0];
457
f->head.head.next = Frame;
460
return (Void_t*)f->data;
462
#endif /*!_lib_alloca || _mal_alloca*/
464
#endif /*_std_malloc || _BLD_INSTRUMENT_ || cray*/