diff options
Diffstat (limited to 'usr/src/lib/libast/common/vmalloc/vmtrace.c')
-rw-r--r-- | usr/src/lib/libast/common/vmalloc/vmtrace.c | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/vmalloc/vmtrace.c b/usr/src/lib/libast/common/vmalloc/vmtrace.c new file mode 100644 index 0000000000..e6f46abb44 --- /dev/null +++ b/usr/src/lib/libast/common/vmalloc/vmtrace.c @@ -0,0 +1,285 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2007 AT&T Knowledge Ventures * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Knowledge Ventures * +* * +* A copy of the License is available at * +* http://www.opensource.org/licenses/cpl1.0.txt * +* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#if defined(_UWIN) && defined(_BLD_ast) + +void _STUB_vmtrace(){} + +#else + +#include "vmhdr.h" + +/* Turn on tracing for regions +** +** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94. +*/ + +static int Trfile = -1; +static char Trbuf[128]; + +#if __STD_C +static char* trstrcpy(char* to, const char* from, int endc) +#else +static char* trstrcpy(to, from, endc) +char* to; +const char* from; +int endc; +#endif +{ reg int n; + + n = strlen(from); + memcpy(to,from,n); + to += n; + if((*to = endc) ) + to += 1; + return to; +} + +/* convert a long value to an ascii representation */ +#if __STD_C +static char* tritoa(Vmulong_t v, int type) +#else +static char* tritoa(v, type) +Vmulong_t v; /* value to convert */ +int type; /* =0 base-16, >0: unsigned base-10, <0: signed base-10 */ +#endif +{ + char* s; + + s = &Trbuf[sizeof(Trbuf) - 1]; + *s-- = '\0'; + + if(type == 0) /* base-16 */ + { reg char* digit = "0123456789abcdef"; + do + { *s-- = digit[v&0xf]; + v >>= 4; + } while(v); + } + else if(type > 0) /* unsigned base-10 */ + { do + { *s-- = (char)('0' + (v%10)); + v /= 10; + } while(v); + } + else /* signed base-10 */ + { 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; +} + +/* generate a trace of some call */ +#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; /* region call was made from */ +Vmuchar_t* oldaddr; /* old data address */ +Vmuchar_t* newaddr; /* new data address */ +size_t size; /* size of piece */ +size_t align; /* alignment */ +#endif +{ + char buf[1024], *bufp, *endbuf; + Vmdata_t* vd = vm->data; + const char* file = 0; + int line = 0; + const Void_t* func = 0; + int comma; + int n; + int m; + + int type; +#define SLOP 64 + + if(oldaddr == (Vmuchar_t*)(-1)) /* printing busy blocks */ + { type = 0; + oldaddr = NIL(Vmuchar_t*); + } + else + { type = vd->mode&VM_METHODS; + VMFLF(vm,file,line,func); + } + + 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, "b", ':'); + else if(type&VM_MTLAST) + bufp = trstrcpy(bufp, "l", ':'); + else if(type&VM_MTPOOL) + bufp = trstrcpy(bufp, "p", ':'); + else if(type&VM_MTPROFILE) + bufp = trstrcpy(bufp, "s", ':'); + else if(type&VM_MTDEBUG) + bufp = trstrcpy(bufp, "d", ':'); + else bufp = trstrcpy(bufp, "u", ':'); + + comma = 0; + if(file && file[0] && line > 0) + { if((bufp + strlen(file) + SLOP) >= endbuf) + { char* f; + for(f = bufp + strlen(file); f > file; --f) + if(f[-1] == '/' || f[-1] == '\\') + break; + file = f; + } + + bufp = trstrcpy(bufp, "file", '='); + n = endbuf - bufp - SLOP - 3; + m = strlen(file); + if(m > n) + { file += (m - n); + bufp = trstrcpy(bufp, "..", '.'); + } + bufp = trstrcpy(bufp, file, ','); + bufp = trstrcpy(bufp, "line", '='); + bufp = trstrcpy(bufp, tritoa((Vmulong_t)line,1), 0); + comma = 1; + } + if(func) + { if(comma) + *bufp++ = ','; + bufp = trstrcpy(bufp, "func", '='); +#if _PACKAGE_ast + bufp = trstrcpy(bufp, (const char*)func, 0); +#else + bufp = trstrcpy(bufp, tritoa((Vmulong_t)func,0), 0); +#endif + comma = 1; + } + if(comma) + *bufp++ = ':'; + + *bufp++ = '\n'; + *bufp = '\0'; + + write(Trfile,buf,(bufp-buf)); +} + +#if DEBUG +#if __STD_C +void _vmmessage(const char* s1, long n1, const char* s2, long n2) +#else +void _vmmessage(s1, n1, s2, n2) +const char* s1; +long n1; +const char* s2; +long n2; +#endif +{ + char buf[1024], *bufp; + + bufp = buf; + bufp = trstrcpy(bufp, "vmalloc", ':'); + if (s1) + { + bufp = trstrcpy(bufp, s1, ':'); + if (n1) + bufp = trstrcpy(bufp, tritoa(n1, 1), ':'); + } + if (s2) + { + bufp = trstrcpy(bufp, s2, ':'); + if (n2) + bufp = trstrcpy(bufp, tritoa(n2, 0), ':'); + } + *bufp++ = '\n'; + write(2,buf,(bufp-buf)); +} +#endif + +#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; +} + +#endif |