misc.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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-2007 *
  9. * by the Xiph.Org Foundation http://www.xiph.org/ *
  10. * *
  11. ********************************************************************/
  12. #define HEAD_ALIGN 32
  13. #include <pthread.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <stdio.h>
  17. #include "vorbis/codec.h"
  18. #define MISC_C
  19. #include "misc.h"
  20. #include <sys/time.h>
  21. static pthread_mutex_t memlock=PTHREAD_MUTEX_INITIALIZER;
  22. static void **pointers=NULL;
  23. static long *insertlist=NULL; /* We can't embed this in the pointer list;
  24. a pointer can have any value... */
  25. static char **files=NULL;
  26. static long *file_bytes=NULL;
  27. static int filecount=0;
  28. static int ptop=0;
  29. static int palloced=0;
  30. static int pinsert=0;
  31. typedef struct {
  32. char *file;
  33. long line;
  34. long ptr;
  35. long bytes;
  36. } head;
  37. long global_bytes=0;
  38. long start_time=-1;
  39. static void *_insert(void *ptr,long bytes,char *file,long line){
  40. ((head *)ptr)->file=file;
  41. ((head *)ptr)->line=line;
  42. ((head *)ptr)->ptr=pinsert;
  43. ((head *)ptr)->bytes=bytes-HEAD_ALIGN;
  44. pthread_mutex_lock(&memlock);
  45. if(pinsert>=palloced){
  46. palloced+=64;
  47. if(pointers){
  48. pointers=(void **)realloc(pointers,sizeof(void **)*palloced);
  49. insertlist=(long *)realloc(insertlist,sizeof(long *)*palloced);
  50. }else{
  51. pointers=(void **)malloc(sizeof(void **)*palloced);
  52. insertlist=(long *)malloc(sizeof(long *)*palloced);
  53. }
  54. }
  55. pointers[pinsert]=ptr;
  56. if(pinsert==ptop)
  57. pinsert=++ptop;
  58. else
  59. pinsert=insertlist[pinsert];
  60. #ifdef _VDBG_GRAPHFILE
  61. {
  62. FILE *out;
  63. struct timeval tv;
  64. static struct timezone tz;
  65. int i;
  66. char buffer[80];
  67. gettimeofday(&tv,&tz);
  68. for(i=0;i<filecount;i++)
  69. if(!strcmp(file,files[i]))break;
  70. if(i==filecount){
  71. filecount++;
  72. if(!files){
  73. files=malloc(filecount*sizeof(*files));
  74. file_bytes=malloc(filecount*sizeof(*file_bytes));
  75. }else{
  76. files=realloc(files,filecount*sizeof(*files));
  77. file_bytes=realloc(file_bytes,filecount*sizeof(*file_bytes));
  78. }
  79. files[i]=strdup(file);
  80. file_bytes[i]=0;
  81. }
  82. file_bytes[i]+=bytes-HEAD_ALIGN;
  83. if(start_time==-1)start_time=(tv.tv_sec*1000)+(tv.tv_usec/1000);
  84. snprintf(buffer,80,"%s%s",file,_VDBG_GRAPHFILE);
  85. out=fopen(buffer,"a");
  86. fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
  87. file_bytes[i]-(bytes-HEAD_ALIGN));
  88. fprintf(out,"%ld, %ld # FILE %s LINE %ld\n",
  89. -start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
  90. file_bytes[i],file,line);
  91. fclose(out);
  92. out=fopen(_VDBG_GRAPHFILE,"a");
  93. fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
  94. global_bytes);
  95. fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
  96. global_bytes+(bytes-HEAD_ALIGN));
  97. fclose(out);
  98. }
  99. #endif
  100. global_bytes+=(bytes-HEAD_ALIGN);
  101. pthread_mutex_unlock(&memlock);
  102. return(ptr+HEAD_ALIGN);
  103. }
  104. static void _ripremove(void *ptr){
  105. int insert;
  106. pthread_mutex_lock(&memlock);
  107. #ifdef _VDBG_GRAPHFILE
  108. {
  109. FILE *out=fopen(_VDBG_GRAPHFILE,"a");
  110. struct timeval tv;
  111. static struct timezone tz;
  112. char buffer[80];
  113. char *file =((head *)ptr)->file;
  114. long bytes =((head *)ptr)->bytes;
  115. int i;
  116. gettimeofday(&tv,&tz);
  117. fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
  118. global_bytes);
  119. fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
  120. global_bytes-((head *)ptr)->bytes);
  121. fclose(out);
  122. for(i=0;i<filecount;i++)
  123. if(!strcmp(file,files[i]))break;
  124. snprintf(buffer,80,"%s%s",file,_VDBG_GRAPHFILE);
  125. out=fopen(buffer,"a");
  126. fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
  127. file_bytes[i]);
  128. fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
  129. file_bytes[i]-bytes);
  130. fclose(out);
  131. file_bytes[i]-=bytes;
  132. }
  133. #endif
  134. global_bytes-=((head *)ptr)->bytes;
  135. insert=((head *)ptr)->ptr;
  136. insertlist[insert]=pinsert;
  137. pinsert=insert;
  138. if(pointers[insert]==NULL){
  139. fprintf(stderr,"DEBUGGING MALLOC ERROR: freeing previously freed memory\n");
  140. fprintf(stderr,"\t%s %ld\n",((head *)ptr)->file,((head *)ptr)->line);
  141. }
  142. if(global_bytes<0){
  143. fprintf(stderr,"DEBUGGING MALLOC ERROR: freeing unmalloced memory\n");
  144. }
  145. pointers[insert]=NULL;
  146. pthread_mutex_unlock(&memlock);
  147. }
  148. void _VDBG_dump(void){
  149. int i;
  150. pthread_mutex_lock(&memlock);
  151. for(i=0;i<ptop;i++){
  152. head *ptr=pointers[i];
  153. if(ptr)
  154. fprintf(stderr,"unfreed bytes from %s:%ld\n",
  155. ptr->file,ptr->line);
  156. }
  157. pthread_mutex_unlock(&memlock);
  158. }
  159. void *_VDBG_malloc(void *ptr,long bytes,char *file,long line){
  160. if(bytes<=0)
  161. fprintf(stderr,"bad malloc request (%ld bytes) from %s:%ld\n",bytes,file,line);
  162. bytes+=HEAD_ALIGN;
  163. if(ptr){
  164. ptr-=HEAD_ALIGN;
  165. _ripremove(ptr);
  166. ptr=realloc(ptr,bytes);
  167. }else{
  168. ptr=malloc(bytes);
  169. memset(ptr,0,bytes);
  170. }
  171. return _insert(ptr,bytes,file,line);
  172. }
  173. void _VDBG_free(void *ptr,char *file,long line){
  174. if(ptr){
  175. ptr-=HEAD_ALIGN;
  176. _ripremove(ptr);
  177. free(ptr);
  178. }
  179. }