#include "vmhdr.h"
static int Trfile = -1;
static char Trbuf[128];
#if __STD_C
static char* trstrcpy(char* to, char* from, int endc)
#else
static char* trstrcpy(to, from, endc)
char* to;
char* from;
int endc;
#endif
{ reg int n;
n = strlen(from);
memcpy(to,from,n);
to += n;
if((*to = endc) )
to += 1;
return to;
}
#if __STD_C
static char* tritoa(Vmulong_t v, int type)
#else
static char* tritoa(v, type)
Vmulong_t v;
int type;
#endif
{
char* s;
s = &Trbuf[sizeof(Trbuf) - 1];
*s-- = '\0';
if(type == 0)
{ reg char* digit = "0123456789abcdef";
do
{ *s-- = digit[v&0xf];
v >>= 4;
} while(v);
*s-- = 'x';
*s-- = '0';
}
else if(type > 0)
{ do
{ *s-- = (char)('0' + (v%10));
v /= 10;
} while(v);
}
else
{ int sign = ((long)v < 0);
if(sign)
v = (Vmulong_t)(-((long)v));
do
{ *s-- = (char)('0' + (v%10));
v /= 10;
} while(v);
if(sign)
*s-- = '-';
}
return s+1;
}
#if __STD_C
static void trtrace(Vmalloc_t* vm,
Vmuchar_t* oldaddr, Vmuchar_t* newaddr, size_t size, size_t align )
#else
static void trtrace(vm, oldaddr, newaddr, size, align)
Vmalloc_t* vm;
Vmuchar_t* oldaddr;
Vmuchar_t* newaddr;
size_t size;
size_t align;
#endif
{
char buf[1024], *bufp, *endbuf;
reg Vmdata_t* vd = vm->data;
reg char* file = NIL(char*);
reg int line = 0;
int type;
#define SLOP 32
if(oldaddr == (Vmuchar_t*)(-1))
{ type = 0;
oldaddr = NIL(Vmuchar_t*);
}
else
{ type = vd->mode&VM_METHODS;
VMFILELINE(vm,file,line);
}
if(Trfile < 0)
return;
bufp = buf; endbuf = buf+sizeof(buf);
bufp = trstrcpy(bufp, tritoa(oldaddr ? VLONG(oldaddr) : 0L, 0), ':');
bufp = trstrcpy(bufp, tritoa(newaddr ? VLONG(newaddr) : 0L, 0), ':');
bufp = trstrcpy(bufp, tritoa((Vmulong_t)size, 1), ':');
bufp = trstrcpy(bufp, tritoa((Vmulong_t)align, 1), ':');
bufp = trstrcpy(bufp, tritoa(VLONG(vm), 0), ':');
if(type&VM_MTBEST)
bufp = trstrcpy(bufp, "best", ':');
else if(type&VM_MTLAST)
bufp = trstrcpy(bufp, "last", ':');
else if(type&VM_MTPOOL)
bufp = trstrcpy(bufp, "pool", ':');
else if(type&VM_MTPROFILE)
bufp = trstrcpy(bufp, "profile", ':');
else if(type&VM_MTDEBUG)
bufp = trstrcpy(bufp, "debug", ':');
else bufp = trstrcpy(bufp, "busy", ':');
if(file && file[0] && line > 0 && (bufp + strlen(file) + SLOP) < endbuf)
{ bufp = trstrcpy(bufp, file, ',');
bufp = trstrcpy(bufp, tritoa((Vmulong_t)line,1), ':');
}
*bufp++ = '\n';
*bufp = '\0';
write(Trfile,buf,(bufp-buf));
}
#if __STD_C
int vmtrace(int file)
#else
int vmtrace(file)
int file;
#endif
{
int fd;
_Vmstrcpy = trstrcpy;
_Vmitoa = tritoa;
_Vmtrace = trtrace;
fd = Trfile;
Trfile = file;
return fd;
}
#if __STD_C
int vmtrbusy(Vmalloc_t* vm)
#else
int vmtrbusy(vm)
Vmalloc_t* vm;
#endif
{
Seg_t* seg;
Vmdata_t* vd = vm->data;
if(Trfile < 0 || !(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE)))
return -1;
for(seg = vd->seg; seg; seg = seg->next)
{ Block_t *b, *endb;
Vmuchar_t* data;
size_t s;
for(b = SEGBLOCK(seg), endb = BLOCK(seg->baddr); b < endb; )
{ if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
continue;
data = DATA(b);
if(vd->mode&VM_MTDEBUG)
{ data = DB2DEBUG(data);
s = DBSIZE(data);
}
else if(vd->mode&VM_MTPROFILE)
s = PFSIZE(data);
else s = SIZE(b)&~BITS;
trtrace(vm, (Vmuchar_t*)(-1), data, s, 0);
b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
}
}
return 0;
}