Files
2026-08-03 18:42:47 +08:00

370 lines
6.8 KiB
C

/*
A* -------------------------------------------------------------------
B* This file contains source code for the PyMOL computer program
C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
D* -------------------------------------------------------------------
E* It is unlawful to modify or remove this copyright notice.
F* -------------------------------------------------------------------
G* Please see the accompanying LICENSE file for further information.
H* -------------------------------------------------------------------
I* Additional authors of this source file include:
-*
-*
-*
Z* -------------------------------------------------------------------
*/
#include"os_memory.h"
#ifdef _os_memory_debug_on
#include<stdio.h>
#include<string.h>
#define GDB_ENTRY
typedef struct DebugRec {
struct DebugRec *next;
char file[64], note[64]; // TOOD: Shouldn't assume <= 64 char path.
int line;
unsigned int size;
int type;
} DebugRec;
#define HASH(x) ((x>>11)&0x3FF)
static DebugRec *HashTable[1024];
static int InitFlag=true;
static int Count;
static int MaxCount;
DebugRec *OSMemoryRemove(void *ptr);
void OSMemoryInit(void);
#endif
void OSMemoryZero(char *p,char *q)
{
register unsigned long count;
register long *a;
int mask;
count = q-p;
mask=sizeof(long)-1;
/* get us word aligned */
while(count&&(((int)p)&mask)) {
count--;
*p++=0;
}
a=(long*)p;
/* now blank efficiently */
while(count>(sizeof(long)*16))
{
count-=(sizeof(long)*16);
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
*a++=0;
}
p=(char*)a;
while(count>0)
{
*p++=0;
count--;
}
}
#ifdef _os_memory_debug_on
void OSMemoryInit(void)
{
int a;
for(a=0;a<1024;a++)
HashTable[a]=NULL;
InitFlag=false;
Count=0;
MaxCount=0;
}
void OSMemoryDump(void)
{
int a;
int cnt=0;
unsigned int tot = 0;
DebugRec *rec;
if(InitFlag) OSMemoryInit();
for(a=0;a<1024;a++)
{
rec=HashTable[a];
while(rec)
{
tot+=rec->size;
printf(" OSMemory: @%10p:%7x:%i %s:%i \n",
(char*)rec+1,rec->size,rec->type,rec->file,rec->line);
rec=rec->next;
cnt++;
}
}
printf(" Memory: %d blocks expected, %d found, %d maximum allocated.\n",
Count,cnt,MaxCount);
printf(" Memory: current memory allocated %x bytes (%0.1f MB).\n",tot,tot/(1024.0*1024));
}
void OSMemoryHashAdd(DebugRec *rec);
DebugRec *OSMemoryHashRemove(void *ptr);
void OSMemoryHashAdd(DebugRec *rec)
{
int hash;
hash=(int)rec;
hash=HASH(hash);
rec->next=HashTable[hash];
HashTable[hash]=rec;
}
DebugRec *OSMemoryHashRemove(void *ptr)
{
DebugRec *rec,*cur,*last;
int hash;
rec=(DebugRec*)ptr;
rec--;
hash=(int)rec;
hash=HASH(hash);
last=NULL;
cur=HashTable[hash];
while(cur)
{
if(cur==rec)
{
if(last)
last->next=cur->next;
else
HashTable[hash]=cur->next;
break;
}
last=cur;
cur=cur->next;
}
return(cur);
}
void *OSMemoryMalloc(unsigned int size,const char *file,int line,int type)
{
DebugRec *rec;
if(InitFlag) OSMemoryInit();
rec=(DebugRec*)malloc(sizeof(DebugRec)+size);
if(!rec)
return(NULL);
int len = strlen(file);
int max_size = sizeof(rec->file) - 1;
if (len > max_size) {
strcpy(rec->file, file + len - max_size);
} else {
strcpy(rec->file, file);
}
rec->file[max_size - 1] = '\0';
rec->line=line;
rec->size=size;
rec->type=type;
OSMemoryHashAdd(rec);
rec++;
Count++;
if(MaxCount<Count) MaxCount=Count;
return((void *) rec);
}
void *OSMemoryCalloc(unsigned int count,unsigned int size,const char *file,int line,int type)
{
DebugRec *rec;
if(InitFlag) OSMemoryInit();
size = size*count;
rec=(DebugRec*)calloc(1,sizeof(DebugRec)+size);
if(!rec)
return(NULL);
int len = strlen(file);
int max_size = sizeof(rec->file) - 1;
if (len > max_size) {
strcpy(rec->file, file + len - max_size);
} else {
strcpy(rec->file, file);
}
rec->file[max_size - 1] = '\0';
rec->line=line;
rec->size=size;
rec->type=type;
OSMemoryHashAdd(rec);
rec++;
Count++;
if(MaxCount<Count) MaxCount=Count;
return((void *) rec);
}
void *OSMemoryRealloc(void *ptr,unsigned int size,const char *file,
int line,int type)
{
DebugRec *rec;
if(InitFlag) OSMemoryInit();
if((!ptr)&&(!size))
{
printf(
"OSMemory-ERR: realloc given (NULL,zero) (%s:%i)\n",
file,line);
#ifdef GDB_ENTRY
OSMemoryDump();
printf("hit ctrl/c to enter debugger\n");
while(true){};
#else
exit(EXIT_FAILURE);
#endif
}
if(!ptr)
return(OSMemoryMalloc(size,file,line,type));
else if(!size)
{
OSMemoryFree(ptr,file,line,type);
return(NULL);
}
else
{
rec=OSMemoryHashRemove(ptr);
if(!rec)
{
printf(
"OSMemory-ERR: realloc() corrupted tree or bad ptr! (%s:%i @%p)\n",
file,line,ptr);
#ifdef GDB_ENTRY
OSMemoryDump();
printf("hit ctrl/c to enter debugger\n");
while(true){};
#else
exit(EXIT_FAILURE);
#endif
}
else
{
if(rec->type!=type)
{
printf("OSMemory-ERR: ptr is of wrong type: %i!=%i (%s:%i)\n",
rec->type,type,file,line);
#ifdef GDB_ENTRY
OSMemoryDump();
printf("hit ctrl/c to enter debugger\n");
while(true){};
#else
exit(EXIT_FAILURE);
#endif
}
rec=(DebugRec*)realloc(rec,size+sizeof(DebugRec));
if(!rec)
{
printf("OSMemory-ERR: realloc() failed reallocation! (%s:%i)\n",
file,line);
#ifdef GDB_ENTRY
OSMemoryDump();
printf("hit ctrl/c to enter debugger\n");
while(true){};
#else
exit(EXIT_FAILURE);
#endif
}
else
{
OSMemoryHashAdd(rec);
rec->size=size;
rec++;
return((void*)rec);
}
}
}
return(ptr);
}
void OSMemoryFree(void *ptr,const char*file,int line,int type)
{
DebugRec *rec;
if(InitFlag) OSMemoryInit();
if(!ptr)
{
printf("OSMemory-ERR: free() called with NULL pointer (%s:%i)\n",
file,line);
#ifdef GDB_ENTRY
OSMemoryDump();
printf("hit ctrl/c to enter debugger\n");
while(true){};
#else
exit(EXIT_FAILURE);
#endif
}
rec=OSMemoryHashRemove(ptr);
if(rec)
{
if(rec->type!=type)
{
printf("OSMemory-ERR: ptr is of wrong type: %i!=%i (%s:%i)\n",
rec->type,type,file,line);
#ifdef GDB_ENTRY
OSMemoryDump();
printf("hit ctrl/c to enter debugger\n");
while(true){};
#else
exit(EXIT_FAILURE);
#endif
}
free(rec);
}
else
{
printf(
"OSMemory-ERR: free(): corrupted tree or bad ptr! (%s:%i @%p)\n",
file,line,ptr);
#ifdef GDB_ENTRY
OSMemoryDump();
printf("hit ctrl/c to enter debugger\n");
while(true){};
#else
exit(EXIT_FAILURE);
#endif
}
Count--;
}
#endif