Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

bbexit.c (2748B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 
      5 struct callsite {
      6 	char *file, *name;
      7 	union coordinate {
      8 		struct { unsigned int index:6,x:10,y:16; } be;
      9 		struct { unsigned int y:16,x:10,index:6; } le;
     10 		unsigned int coord;
     11 	} u;
     12 } *_caller;
     13 
     14 static struct _bbdata {
     15 	struct _bbdata *link;
     16 	unsigned npoints, *counts;
     17 	union coordinate *coords;
     18 	char **files;
     19 	struct func {
     20 		struct func *link;
     21 		struct caller {
     22 			struct caller *link;
     23 			struct callsite *caller;
     24 			unsigned count;
     25 		} *callers;
     26 		char *name;
     27 		union coordinate src;
     28 	} *funcs;
     29 } tail, *_bblist = &tail;
     30 
     31 static void unpack(unsigned int coord, int *index, int *x, int *y) {
     32 	static union { int x; char endian; } little = { 1 };
     33 	union coordinate u;
     34 
     35 	u.coord = coord;
     36 	if (little.endian) {
     37 		*index = u.le.index;
     38 		*x = u.le.x;
     39 		*y = u.le.y;
     40 	} else {
     41 		*index = u.be.index;
     42 		*x = u.be.x;
     43 		*y = u.be.y;
     44 	}
     45 }				
     46 
     47 static void profout(struct _bbdata *p, FILE *fp) {
     48 	int i, index, x, y;
     49 	struct func *f;
     50 	struct caller *q;
     51 
     52 	for (i = 0; p->files[i]; i++)
     53 		;
     54 	fprintf(fp, "%d\n", i);
     55 	for (i = 0; p->files[i]; i++)
     56 		fprintf(fp, "%s\n", p->files[i]);
     57 	for (i = 0, f = p->funcs; f; i++, f = f->link)
     58 		if (q = f->callers)
     59 			for (i--; q; q = q->link)
     60 				i++;
     61 	fprintf(fp, "%d\n", i);
     62 	for (f = p->funcs; f; f = f->link) {
     63 		int n = 0;
     64 		for (q = f->callers; q; n += q->count, q = q->link) {
     65 			unpack(f->src.coord, &index, &x, &y);
     66 			fprintf(fp, "%s %d %d %d %d", f->name, index, x, y, q->count);
     67 			if (q->caller) {
     68 				unpack(q->caller->u.coord, &index, &x, &y);
     69 				fprintf(fp, " %s %s %d %d\n", q->caller->name, q->caller->file, x, y);
     70 			} else
     71 				fprintf(fp, " ? ? 0 0\n");
     72 		}
     73 		if (n == 0) {
     74 			unpack(f->src.coord, &index, &x, &y);
     75 			fprintf(fp, "%s %d %d %d 0 ? ? 0 0\n", f->name, index, x, y);
     76 		}
     77 	}		
     78 	fprintf(fp, "%d\n", p->npoints);
     79 	for (i = 0; i < p->npoints; i++) {
     80 		unpack(p->coords[i].coord, &index, &x, &y);
     81 		fprintf(fp, "%d %d %d %d\n", index, x, y, p->counts[i]);
     82 	}
     83 }
     84 
     85 static void bbexit(void) {
     86 	FILE *fp;
     87 
     88 	if (_bblist != &tail && (fp = fopen("prof.out", "a"))) {
     89 		for ( ; _bblist != &tail; _bblist = _bblist->link)
     90 			profout(_bblist, fp);
     91 		fclose(fp);
     92 	}
     93 }
     94 
     95 void _epilogue(struct func *callee) {
     96 	_caller = 0;
     97 }
     98 
     99 void _prologue(struct func *callee, struct _bbdata *yylink) {
    100 	static struct caller callers[4096];
    101 	static int next;
    102 	struct caller *p;
    103 
    104 	if (!yylink->link) {
    105 		yylink->link = _bblist;
    106 		_bblist = yylink;
    107 		if (next == 0)
    108 			atexit(bbexit);
    109 	}
    110 	for (p = callee->callers; p; p = p->link)
    111 		if (p->caller == _caller) {
    112 			p->count++;
    113 			break;
    114 		}
    115 	if (!p && next < sizeof callers/sizeof callers[0]) {
    116 		p = &callers[next++];
    117 		p->caller = _caller;
    118 		p->count = 1;
    119 		p->link = callee->callers;
    120 		callee->callers = p;
    121 	}
    122 	_caller = 0;
    123 }