00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #if ! CMK_MEMORY_BUILD_OS
00020
00021 #include "memory-gnu.C"
00022 #endif
00023
00024
00025 typedef struct Slot Slot;
00026
00027
00028
00029
00030 struct Slot {
00031
00032 Slot *next;
00033 Slot *prev;
00034
00035
00036 int userSize;
00037
00038
00039 #define SLOTMAGIC 0x8402a5f5
00040 #define SLOTMAGIC_VALLOC 0x7402a5f5
00041 #define SLOTMAGIC_FREED 0xDEADBEEF
00042 int magic;
00043
00044
00045 #define STACK_LEN 9
00046 void *from[STACK_LEN];
00047 };
00048
00049
00050 static char *Slot_toUser(Slot *s) {
00051 return ((char *)s)+sizeof(Slot);
00052 }
00053
00054
00055 static Slot *Slot_fmUser(void *user) {
00056 char *cu=(char *)user;
00057 Slot *s=(Slot *)(cu-sizeof(Slot));
00058 return s;
00059 }
00060
00061 static void printSlot(Slot *s) {
00062 CmiPrintf("[%d] Leaked block of %d bytes at %p:\n",
00063 CmiMyPe(), s->userSize, Slot_toUser(s));
00064 CmiBacktracePrint(s->from,STACK_LEN);
00065 }
00066
00067
00068
00069
00070 Slot slot_first_storage={&slot_first_storage,&slot_first_storage};
00071 Slot *slot_first=&slot_first_storage;
00072
00073 #define CMI_MEMORY_ROUTINES 1
00074
00075
00076 void CmiMemoryMark(void) {
00077 CmiMemLock();
00078
00079 slot_first=(Slot *)mm_malloc(sizeof(Slot));
00080 slot_first->next=slot_first->prev=slot_first;
00081 CmiMemUnlock();
00082 }
00083
00084
00085 void CmiMemoryMarkBlock(void *blk) {
00086 Slot *s=Slot_fmUser(blk);
00087 CmiMemLock();
00088 if (s->magic!=SLOTMAGIC) CmiAbort("CmiMemoryMarkBlock called on non-malloc'd block!\n");
00089
00090 s->next->prev=s->prev;
00091 s->prev->next=s->next;
00092 s->prev=s->next=s;
00093 CmiMemUnlock();
00094 }
00095
00096
00097 void CmiMemorySweep(const char *where)
00098 {
00099 Slot *cur;
00100 int nBlocks=0,nBytes=0;
00101 CmiMemLock();
00102 cur=slot_first->next;
00103 CmiPrintf("[%d] ------- LEAK CHECK: %s -----\n",CmiMyPe(), where);
00104 while (cur!=slot_first) {
00105 printSlot(cur);
00106 nBlocks++; nBytes+=cur->userSize;
00107 cur=cur->next;
00108 }
00109 if (nBlocks) {
00110 CmiPrintf("[%d] Total leaked memory: %d blocks, %d bytes\n",
00111 CmiMyPe(),nBlocks,nBytes);
00112
00113 }
00114 CmiMemUnlock();
00115 CmiMemoryMark();
00116 }
00117 void CmiMemoryCheck(void) {}
00118
00119
00120
00121 static int memoryTraceDisabled = 0;
00122
00123
00124 static void *setSlot(Slot *s,int userSize) {
00125 char *user=Slot_toUser(s);
00126
00127
00128 s->next=slot_first->next;
00129 s->prev=slot_first;
00130 s->next->prev=s;
00131 s->prev->next=s;
00132
00133 s->magic=SLOTMAGIC;
00134 s->userSize=userSize;
00135 {
00136 int n=STACK_LEN;
00137 if (memoryTraceDisabled==0) {
00138 memoryTraceDisabled = 1;
00139 CmiBacktraceRecord(s->from,3,&n);
00140 memoryTraceDisabled = 0;
00141 } else {
00142 s->from[0] = (void*)10;
00143 s->from[1] = (void*)9;
00144 s->from[2] = (void*)8;
00145 s->from[3] = (void*)7;
00146 }
00147 }
00148 return (void *)user;
00149 }
00150
00151
00152 static void freeSlot(Slot *s) {
00153
00154 s->next->prev=s->prev;
00155 s->prev->next=s->next;
00156 s->prev=s->next=(Slot *)0x0F00;
00157
00158 s->magic=SLOTMAGIC_FREED;
00159 s->userSize=-1;
00160 }
00161
00162
00163
00164
00165
00166 static void status(const char *msg) {
00167 if (CmiMyPe()==0 && !CmiArgGivingUsage()) {
00168 CmiPrintf("%s",msg);
00169 }
00170 }
00171 static void meta_init(char **argv)
00172 {
00173 status("Converse -memory mode: leak");
00174 status("\n");
00175 }
00176
00177 static void *meta_malloc(size_t size)
00178 {
00179 Slot *s=(Slot *)mm_malloc(sizeof(Slot)+size);
00180 if (s==NULL) return s;
00181 return setSlot(s,size);
00182 }
00183
00184 static void meta_free(void *mem)
00185 {
00186 Slot *s;
00187 if (mem==NULL) return;
00188
00189 s=((Slot *)mem)-1;
00190 if (s->magic==SLOTMAGIC_VALLOC)
00191 {
00192 freeSlot(s);
00193 mm_free(((char *)mem)-CmiGetPageSize());
00194 }
00195 else if (s->magic==SLOTMAGIC)
00196 {
00197 freeSlot(s);
00198 mm_free(s);
00199 }
00200 else if (s->magic==SLOTMAGIC_FREED)
00201 CmiAbort("Free'd block twice");
00202 else
00203 CmiAbort("Free'd non-malloc'd block");
00204 }
00205
00206 static void *meta_calloc(size_t nelem, size_t size)
00207 {
00208 void *area=meta_malloc(nelem*size);
00209 if (area != NULL) memset(area,0,nelem*size);
00210 return area;
00211 }
00212
00213 static void meta_cfree(void *mem)
00214 {
00215 meta_free(mem);
00216 }
00217
00218 static void *meta_realloc(void *oldBuffer, size_t newSize)
00219 {
00220 void *newBuffer = meta_malloc(newSize);
00221 if ( newBuffer && oldBuffer ) {
00222
00223 Slot *o=Slot_fmUser(oldBuffer);
00224 size_t size=o->userSize;
00225 if (size>newSize) size=newSize;
00226 if (size > 0)
00227 memcpy(newBuffer, oldBuffer, size);
00228 }
00229 if (oldBuffer)
00230 meta_free(oldBuffer);
00231 return newBuffer;
00232 }
00233
00234 static void *meta_memalign(size_t align, size_t size)
00235 {
00236
00237 char *alloc=(char *)mm_memalign(align,CmiGetPageSize()+size);
00238 Slot *s=(Slot *)(alloc+CmiGetPageSize()-sizeof(Slot));
00239 void *user=setSlot(s,size);
00240 s->magic=SLOTMAGIC_VALLOC;
00241 return user;
00242 }
00243
00244 static int meta_posix_memalign(void **outptr, size_t align, size_t size)
00245 {
00246
00247 int ret = mm_posix_memalign(outptr,align,CmiGetPageSize()+size);
00248 if (ret != 0)
00249 return ret;
00250 char *alloc=(char *)*outptr;
00251 Slot *s=(Slot *)(alloc+CmiGetPageSize()-sizeof(Slot));
00252 void *user=setSlot(s,size);
00253 s->magic=SLOTMAGIC_VALLOC;
00254 *outptr = user;
00255 return 0;
00256 }
00257
00258 static void *meta_aligned_alloc(size_t align, size_t size)
00259 {
00260
00261 char *alloc=(char *)mm_aligned_alloc(align,CmiGetPageSize()+size);
00262 Slot *s=(Slot *)(alloc+CmiGetPageSize()-sizeof(Slot));
00263 void *user=setSlot(s,size);
00264 s->magic=SLOTMAGIC_VALLOC;
00265 return user;
00266 }
00267
00268 static void *meta_valloc(size_t size)
00269 {
00270 return meta_memalign(CmiGetPageSize(),size);
00271 }
00272
00273 static void *meta_pvalloc(size_t size)
00274 {
00275 const size_t pagesize = CmiGetPageSize();
00276 return meta_memalign(pagesize, (size + pagesize - 1) & ~(pagesize - 1));
00277 }