1 #include <u.h> 2 #include <libc.h> 3 4 extern long* _clock; 5 extern long _callpc(void**); 6 extern long _savearg(void); 7 8 typedef struct Plink Plink; 9 struct Plink 10 { 11 Plink *old; /* known to be 0(ptr) */ 12 Plink *down; 13 Plink *link; 14 long pc; 15 long count; 16 long time; /* known to be 20(ptr) */ 17 }; 18 19 struct 20 { 21 Plink *pp; /* known to be 0(ptr) */ 22 Plink *next; /* known to be 4(ptr) */ 23 Plink *last; 24 Plink *first; 25 } __prof; 26 27 ulong 28 _profin(void) 29 { 30 void *dummy; 31 long pc; 32 Plink *pp, *p; 33 ulong arg; 34 35 arg = _savearg(); 36 pc = _callpc(&dummy); 37 pp = __prof.pp; 38 if(pp == 0) 39 return arg; 40 41 for(p=pp->down; p; p=p->link) 42 if(p->pc == pc) 43 goto out; 44 p = __prof.next + 1; 45 if(p >= __prof.last) { 46 __prof.pp = 0; 47 write(2, "/env/profsize too small\n", 24); 48 return arg; 49 } 50 __prof.next = p; 51 p->link = pp->down; 52 pp->down = p; 53 p->pc = pc; 54 p->old = pp; 55 p->down = 0; 56 p->count = 0; 57 58 out: 59 __prof.pp = p; 60 p->count++; 61 p->time += *_clock; 62 return arg; /* disgusting linkage */ 63 } 64 65 ulong 66 _profout(void) 67 { 68 Plink *p; 69 ulong arg; 70 71 arg = _savearg(); 72 p = __prof.pp; 73 if(p) { 74 p->time -= *_clock; 75 __prof.pp = p->old; 76 } 77 return arg; 78 } 79 80 void 81 _profdump(void) 82 { 83 int f; 84 long n; 85 Plink *p; 86 char *vp; 87 88 __prof.pp = 0; 89 f = create("prof.out", 1, 0666); 90 if(f < 0) { 91 perror("create prof.out"); 92 return; 93 } 94 __prof.first->time = -*_clock; 95 vp = (char*)__prof.first; 96 for(p = __prof.first; p <= __prof.next; p++) { 97 /* 98 * short down 99 */ 100 n = 0xffff; 101 if(p->down) 102 n = p->down - __prof.first; 103 vp[0] = n>>8; 104 vp[1] = n; 105 106 /* 107 * short right 108 */ 109 n = 0xffff; 110 if(p->link) 111 n = p->link - __prof.first; 112 vp[2] = n>>8; 113 vp[3] = n; 114 vp += 4; 115 116 /* 117 * long pc 118 */ 119 n = p->pc; 120 vp[0] = n>>24; 121 vp[1] = n>>16; 122 vp[2] = n>>8; 123 vp[3] = n; 124 vp += 4; 125 126 /* 127 * long count 128 */ 129 n = p->count; 130 vp[0] = n>>24; 131 vp[1] = n>>16; 132 vp[2] = n>>8; 133 vp[3] = n; 134 vp += 4; 135 136 /* 137 * long time 138 */ 139 n = -p->time; 140 vp[0] = n>>24; 141 vp[1] = n>>16; 142 vp[2] = n>>8; 143 vp[3] = n; 144 vp += 4; 145 } 146 write(f, (char*)__prof.first, vp - (char*)__prof.first); 147 close(f); 148 } 149 150 void 151 _profmain(void) 152 { 153 char ename[50]; 154 int n, f; 155 156 n = 2000; 157 f = open("/env/profsize", OREAD); 158 if(f >= 0) { 159 memset(ename, 0, sizeof(ename)); 160 read(f, ename, sizeof(ename)-1); 161 close(f); 162 n = atol(ename); 163 } 164 __prof.first = sbrk(n*sizeof(Plink)); 165 __prof.last = sbrk(0); 166 __prof.next = __prof.first; 167 atexit(_profdump); 168 *_clock = 1; 169 } 170