misc.c revision 0f6f2525f7b19c7de18bafe464b5ced1c714430a
1/********************************************************************
2 *                                                                  *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7 *                                                                  *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
9 * by the XIPHOPHORUS Company http://www.xiph.org/                  *
10 *                                                                  *
11 ********************************************************************/
12
13#define HEAD_ALIGN 64
14#include <stdlib.h>
15#include <string.h>
16#include <stdio.h>
17#define MISC_C
18#include "misc.h"
19//#include <sys/time.h>
20
21static void **pointers=NULL;
22static long *insertlist=NULL; /* We can't embed this in the pointer list;
23			  a pointer can have any value... */
24
25static char **files=NULL;
26static long *file_bytes=NULL;
27static int  filecount=0;
28
29static int ptop=0;
30static int palloced=0;
31static int pinsert=0;
32
33typedef struct {
34  char *file;
35  long line;
36  long ptr;
37  long bytes;
38} head;
39
40long global_bytes=0;
41long start_time=-1;
42
43static void *_insert(void *ptr,long bytes,char *file,long line){
44  ((head *)ptr)->file=file;
45  ((head *)ptr)->line=line;
46  ((head *)ptr)->ptr=pinsert;
47  ((head *)ptr)->bytes=bytes-HEAD_ALIGN;
48
49  if(pinsert>=palloced){
50    palloced+=64;
51    if(pointers){
52      pointers=(void **)realloc(pointers,sizeof(void **)*palloced);
53      insertlist=(long *)realloc(insertlist,sizeof(long *)*palloced);
54    }else{
55      pointers=(void **)malloc(sizeof(void **)*palloced);
56      insertlist=(long *)malloc(sizeof(long *)*palloced);
57    }
58  }
59
60  pointers[pinsert]=ptr;
61
62  if(pinsert==ptop)
63    pinsert=++ptop;
64  else
65    pinsert=insertlist[pinsert];
66
67#ifdef _VDBG_GRAPHFILE
68  {
69    FILE *out;
70    struct timeval tv;
71    static struct timezone tz;
72    int i;
73    char buffer[80];
74    gettimeofday(&tv,&tz);
75
76    for(i=0;i<filecount;i++)
77      if(!strcmp(file,files[i]))break;
78
79    if(i==filecount){
80      filecount++;
81      if(!files){
82	files=malloc(filecount*sizeof(*files));
83	file_bytes=malloc(filecount*sizeof(*file_bytes));
84      }else{
85	files=realloc(files,filecount*sizeof(*files));
86	file_bytes=realloc(file_bytes,filecount*sizeof(*file_bytes));
87      }
88      files[i]=strdup(file);
89      file_bytes[i]=0;
90    }
91
92    file_bytes[i]+=bytes-HEAD_ALIGN;
93
94    if(start_time==-1)start_time=(tv.tv_sec*1000)+(tv.tv_usec/1000);
95
96    snprintf(buffer,80,"%s",file);
97    if(strchr(buffer,'.'))strchr(buffer,'.')[0]=0;
98    strcat(buffer,_VDBG_GRAPHFILE);
99    out=fopen(buffer,"a");
100    fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
101	    file_bytes[i]-(bytes-HEAD_ALIGN));
102    fprintf(out,"%ld, %ld # FILE %s LINE %ld\n",
103	    -start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
104	    file_bytes[i],file,line);
105    fclose(out);
106
107    out=fopen("total"_VDBG_GRAPHFILE,"a");
108    fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
109	    global_bytes);
110    fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
111	    global_bytes+(bytes-HEAD_ALIGN));
112    fclose(out);
113  }
114#endif
115
116  global_bytes+=(bytes-HEAD_ALIGN);
117
118  return(void *)(((char *)ptr)+HEAD_ALIGN);
119}
120
121static void _ripremove(void *ptr){
122  int insert;
123
124#ifdef _VDBG_GRAPHFILE
125  {
126    FILE *out=fopen("total"_VDBG_GRAPHFILE,"a");
127    struct timeval tv;
128    static struct timezone tz;
129    char buffer[80];
130    char *file =((head *)ptr)->file;
131    long bytes =((head *)ptr)->bytes;
132    int i;
133
134    gettimeofday(&tv,&tz);
135    fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
136	    global_bytes);
137    fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
138	    global_bytes-((head *)ptr)->bytes);
139    fclose(out);
140
141    for(i=0;i<filecount;i++)
142      if(!strcmp(file,files[i]))break;
143
144    snprintf(buffer,80,"%s",file);
145    if(strchr(buffer,'.'))strchr(buffer,'.')[0]=0;
146    strcat(buffer,_VDBG_GRAPHFILE);
147    out=fopen(buffer,"a");
148    fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
149	    file_bytes[i]);
150    fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
151	    file_bytes[i]-bytes);
152    fclose(out);
153
154    file_bytes[i]-=bytes;
155
156  }
157#endif
158
159  global_bytes-=((head *)ptr)->bytes;
160
161  insert=((head *)ptr)->ptr;
162  insertlist[insert]=pinsert;
163  pinsert=insert;
164
165  if(pointers[insert]==NULL){
166    fprintf(stderr,"DEBUGGING MALLOC ERROR: freeing previously freed memory\n");
167    fprintf(stderr,"\t%s %ld\n",((head *)ptr)->file,((head *)ptr)->line);
168  }
169
170  if(global_bytes<0){
171    fprintf(stderr,"DEBUGGING MALLOC ERROR: freeing unmalloced memory\n");
172  }
173
174  pointers[insert]=NULL;
175}
176
177void _VDBG_dump(void){
178  int i;
179  for(i=0;i<ptop;i++){
180    head *ptr=pointers[i];
181    if(ptr)
182      fprintf(stderr,"unfreed bytes from %s:%ld\n",
183	      ptr->file,ptr->line);
184  }
185
186}
187
188extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line){
189  bytes+=HEAD_ALIGN;
190  if(ptr){
191    ptr=(void *)(((char *)ptr)-HEAD_ALIGN);
192    _ripremove(ptr);
193    ptr=realloc(ptr,bytes);
194  }else{
195    ptr=malloc(bytes);
196    memset(ptr,0,bytes);
197  }
198  return _insert(ptr,bytes,file,line);
199}
200
201extern void _VDBG_free(void *ptr,char *file,long line){
202  if(ptr){
203    ptr=(void *)(((char *)ptr)-HEAD_ALIGN);
204    _ripremove(ptr);
205    free(ptr);
206  }
207}
208
209