libburn/libcevap/smem.c

446 lines
8.0 KiB
C

#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define Smem_included_by_smem_C
#include "smem.h"
/* ------------------------------ SmemiteM ----------------------------- */
int Smemitem_new(item,data,size,next,hash_start,flag)
struct SmemiteM **item;
char *data;
size_t size;
struct SmemiteM *next;
struct SmemiteM **hash_start;
int flag;
{
struct SmemiteM *t;
*item= t= (struct SmemiteM *) malloc(sizeof(struct SmemiteM));
if(t==NULL)
return(-1);
t->data= data;
t->size= size;
t->prev= NULL;
t->next= next;
#ifdef Smem_with_hasH
t->hash_next= NULL;
t->hash_prev= NULL;
#endif /* Smem_with_hasH */
if(next!=NULL) {
if(next->prev!=NULL) {
t->prev= next->prev;
next->prev->next= t;
}
next->prev= t;
}
#ifdef Smem_with_hasH
if(hash_start!=NULL) {
t->hash_next= *hash_start;
if(t->hash_next!=NULL) {
t->hash_next->hash_prev= t;
}
*hash_start= t;
}
#endif /* Smem_with_hasH */
return(1);
}
int Smemitem_destroy(in_item,hash_start,flag)
struct SmemiteM **in_item;
struct SmemiteM **hash_start;
int flag;
{
struct SmemiteM *item;
item= *in_item;
if(item==NULL)
return(0);
if(item==Smem_start_iteM)
Smem_start_iteM= item->next;
if(item->prev!=NULL)
item->prev->next= item->next;
if(item->next!=NULL)
item->next->prev= item->prev;
#ifdef Smem_with_hasH
if(hash_start!=NULL) {
if(item==*hash_start)
*hash_start= item->hash_next;
if(item->hash_prev!=NULL)
item->hash_prev->hash_next= item->hash_next;
if(item->hash_next!=NULL)
item->hash_next->hash_prev= item->hash_prev;
}
#endif /* Smem_with_hasH */
free((char *) item);
*in_item= NULL;
return(1);
}
int Smemitem_report(item,line,flag)
struct SmemiteM *item;
char line[1024];
int flag;
{
char *cpt;
int i,upto;
sprintf(line,"%4lu bytes at %8.8lx ",(unsigned long) item->size,
(unsigned long) item->data);
cpt= line+strlen(line);
if(item->size<=256)
upto= item->size;
else
upto= 256;
if(item->data!=NULL) {
strcpy(cpt,"= \"");
cpt+= 3;
for(i=0;i<upto;i++){
if(item->data[i]<32 || item->data[i]>=127 || item->data[i]=='\\') {
sprintf(cpt,"\\%2.2X",(unsigned char) item->data[i]);
cpt+= 3;
} else {
*(cpt++)= item->data[i];
}
}
if(i<item->size) {
sprintf(cpt,"\" [truncated]");
} else {
*(cpt++)= '"';
*cpt= 0;
}
}
return(1);
}
int Smemitem_stderr(item,flag)
struct SmemiteM *item;
int flag;
{
char line[1024];
Smemitem_report(item,line,0);
fprintf(stderr,"%s\n",line);
return(1);
}
/* -------------------------------- Smem ------------------------------ */
int Smem_protest(line,flag)
char *line;
int flag;
{
fprintf(stderr,"%s\n",line);
return(1);
}
int Smem_hashindex(ptr,flag)
char *ptr;
int flag;
{
unsigned long idx;
idx= (unsigned long) ptr;
return((idx>>Smem_hashshifT)%(Smem_hashsizE));
}
/* find a certain memory item */
struct SmemiteM *Smem_find_item(ptr,flag)
char *ptr;
int flag;
{
int misscount= 0,idx;
struct SmemiteM *current;
#ifdef Smem_with_hasH
idx= Smem_hashindex(ptr,0);
for(current= Smem_hasH[idx];current!=NULL;current= current->hash_next) {
if(current->data==ptr)
return(current);
misscount++;
}
#else /* Smem_with_hasH */
for(current= Smem_start_iteM;current!=NULL;current= current->next) {
if(current->data==ptr)
return(current);
misscount++;
}
#endif /* ! Smem_with_hasH */
return(NULL);
}
int Smem_search_and_delete(ptr,flag)
char *ptr;
int flag;
/*
bit0= revoke registration : decrement counters
*/
{
int idx;
struct SmemiteM *current;
current= Smem_find_item(ptr,0);
if(current==NULL)
return(0);
Smem_record_counT--;
Smem_record_byteS-= current->size;
idx= Smem_hashindex(ptr,0);
Smemitem_destroy(&current,&(Smem_hasH[idx]),0);
Smem_hash_counteR[idx]-= 1.0;
if(flag&1) {
Smem_malloc_counT--;
Smem_pending_counT--;
}
return(1);
}
char *Smem_malloc(size)
size_t size;
{
int idx;
char *cpt;
if(size==0) {
Smem_protest("########### smem.c : malloc(0) caught",0);
return(NULL);
}
/* if(size==1032)
cpt= NULL; / * set breakpoint here to find requests of certain size */
cpt= (char *) malloc(size);
if(cpt==NULL) {
char text[161];
sprintf(text,"########### smem.c : malloc( %lu ) returned NULL",
(unsigned long) size);
Smem_protest(text,0);
return(NULL);
}
/* if(cpt==0x080a1e20)
cpt= NULL; / * set breakpoint here to find origin of certain address */
Smem_malloc_counT++;
Smem_pending_counT++;
if(Smem_record_itemS) {
idx= Smem_hashindex(cpt,0);
Smem_hash_counteR[idx]+= 1.0;
if(Smemitem_new(&Smem_start_iteM,cpt,size,Smem_start_iteM,
&(Smem_hasH[idx]),0)<=0) {
Smem_protest(
"########### smem.c : malloc( sizeof(SmemiteM) ) returned NULL",0);
return(NULL);
}
Smem_record_counT++;
Smem_record_byteS+= size;
}
return(cpt);
}
int Smem_free(ptr)
char *ptr;
{
if(ptr==NULL) {
Smem_protest("########### smem.c : free() of NULL pointer caught",0);
return(0);
}
if(Smem_record_itemS) {
if(Smem_search_and_delete(ptr,0)<=0) {
Smem_protest("########### smem.c : free() of unrecorded pointer caught",0);
return(0);
}
}
Smem_free_counT++;
Smem_pending_counT--;
free(ptr);
return(1);
}
int Smem_report(line,flag)
char line[1024];
int flag;
{
sprintf(line,"malloc= %.f , free= %.f , pending= %.f",
Smem_malloc_counT,Smem_free_counT,Smem_pending_counT);
if(Smem_record_itemS) {
sprintf(line+strlen(line)," , bytes=%.f , records= %.f",
Smem_record_byteS,Smem_record_counT);
}
return(1);
}
int Smem_stderr(flag)
int flag;
/*
bit0= report 50 youngest pending items too
bit1= do not report if nothing is pending
*/
{
struct SmemiteM *current;
char line[1024];
int i= 0;
if(flag&2)
if(Smem_pending_counT==0.0
&& Smem_record_counT==0.0
&& Smem_record_byteS==0.0)
return(2);
Smem_report(line,0);
fprintf(stderr,"%s\n",line);
if(flag&1) {
for(current= Smem_start_iteM;current!=NULL;current= current->next) {
Smemitem_stderr(current,0);
if(++i>=50)
break;
}
if(current!=NULL)
if(current->next!=NULL)
fprintf(stderr,"[list truncated]\n");
}
return(1);
}
int Smem_set_record_items(value)
int value;
{
int i;
if(!Smem_hash_initializeD) {
for(i=0;i<Smem_hashsizE;i++) {
Smem_hasH[i]= NULL;
Smem_hash_counteR[i]= 0.0;
}
Smem_hash_initializeD= 1;
}
Smem_record_itemS= value;
return(1);
}
int Smem_is_recorded(ptr,flag)
char *ptr;
int flag;
/*
bit0= complain if return(0)
*/
{
if(Smem_record_itemS==0)
return(2);
if(Smem_find_item(ptr,0)!=NULL)
return(1);
if(flag&1)
Smem_protest("########### smem.c : free() of unrecorded pointer caught",0);
return(0);
}
/* A simple C string cloner */
int Smem_clone_string(ptr,text)
char **ptr;
char *text;
{
*ptr= Smem_malloC(strlen(text)+1);
if(*ptr==NULL)
return(-1);
strcpy(*ptr,text);
return(1);
}
/* ----------------- for usage via debugger commands --------------------- */
/* find a certain memory item */
struct SmemiteM *Smem_find_data(ptr)
char *ptr;
{
return(Smem_find_item(ptr,0));
}
/* browsing the list */
struct SmemiteM *Smem_fetch_item(step,flag)
int step;
int flag;
/*
bit0= reset cursor (and therefore address absolutely)
*/
{
static struct SmemiteM *current= NULL;
if((flag&1)||current==NULL)
current= Smem_start_iteM;
if(step>0) {
for(;current!=NULL;current= current->next) {
if(step==0)
return(current);
step--;
}
} else if(step<0) {
for(;current!=NULL;current= current->prev) {
if(step==0)
return(current);
step++;
}
} else {
return(current);
}
return(NULL);
}
int Smem_print_hash_counter() {
int i;
for(i=0;i<Smem_hashsizE;i++)
printf("%4d : %10.f\n",i,Smem_hash_counteR[i]);
return(1);
}
/* delete all recorded memory items */
int Smem_delete_all_items()
{
int ret;
while(Smem_start_iteM!=NULL) {
ret= Smem_free(Smem_start_iteM->data);
if(ret<=0)
return(0);
}
return(1);
}