a4a1722000-12-05Per Hedbor /* $Id: block_alloc.h,v 1.27 2000/12/05 21:08:15 per Exp $ */
4218011999-01-31Fredrik Hübinette (Hubbe) #undef PRE_INIT_BLOCK #undef INIT_BLOCK #undef EXIT_BLOCK #undef BLOCK_ALLOC
fc2c831999-04-01Fredrik Hübinette (Hubbe) #undef PTR_HASH_ALLOC
cfa7d82000-01-27Fredrik Hübinette (Hubbe) #undef COUNT_BLOCK #undef COUNT_OTHER
4218011999-01-31Fredrik Hübinette (Hubbe) 
2bfcfe1998-03-27Fredrik Hübinette (Hubbe) #define PRE_INIT_BLOCK(X)
21ed0e1998-02-19Fredrik Hübinette (Hubbe) #define INIT_BLOCK(X) #define EXIT_BLOCK(X)
cfa7d82000-01-27Fredrik Hübinette (Hubbe) #define COUNT_BLOCK(X) #define COUNT_OTHER()
4218011999-01-31Fredrik Hübinette (Hubbe) 
fc2c831999-04-01Fredrik Hübinette (Hubbe) #define BLOCK_ALLOC(DATA,BSIZE) \ \ struct PIKE_CONCAT(DATA,_block) \ { \ struct PIKE_CONCAT(DATA,_block) *next; \ struct DATA x[BSIZE]; \ }; \ \ static struct PIKE_CONCAT(DATA,_block) *PIKE_CONCAT(DATA,_blocks)=0; \ static struct DATA *PIKE_CONCAT3(free_,DATA,s)=0; \ \ struct DATA *PIKE_CONCAT(alloc_,DATA)(void) \ { \ struct DATA *tmp; \ if(!PIKE_CONCAT3(free_,DATA,s)) \ { \ struct PIKE_CONCAT(DATA,_block) *n; \ int e; \ n=(struct PIKE_CONCAT(DATA,_block) *) \ malloc(sizeof(struct PIKE_CONCAT(DATA,_block))); \ if(!n) \ { \ fprintf(stderr,"Fatal: out of memory.\n"); \ exit(17); \ } \ n->next=PIKE_CONCAT(DATA,_blocks); \ PIKE_CONCAT(DATA,_blocks)=n; \ \ for(e=0;e<BSIZE;e++) \ { \
f87e032000-11-25Henrik Grubbström (Grubba)  n->x[e].BLOCK_ALLOC_NEXT=(void *)PIKE_CONCAT3(free_,DATA,s); \
fc2c831999-04-01Fredrik Hübinette (Hubbe)  PRE_INIT_BLOCK( (n->x+e) ); \ PIKE_CONCAT3(free_,DATA,s)=n->x+e; \ } \ } \ \ tmp=PIKE_CONCAT3(free_,DATA,s); \
f87e032000-11-25Henrik Grubbström (Grubba)  PIKE_CONCAT3(free_,DATA,s)=(struct DATA *)tmp->BLOCK_ALLOC_NEXT; \
60d9872000-03-23Fredrik Hübinette (Hubbe)  DO_IF_DMALLOC( dmalloc_register(tmp,sizeof(struct DATA), DMALLOC_LOCATION()); )\
fc2c831999-04-01Fredrik Hübinette (Hubbe)  INIT_BLOCK(tmp); \ return tmp; \ } \ \ void PIKE_CONCAT(really_free_,DATA)(struct DATA *d) \ { \ EXIT_BLOCK(d); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  DO_IF_DMALLOC( dmalloc_unregister(d, 1); ) \
f87e032000-11-25Henrik Grubbström (Grubba)  d->BLOCK_ALLOC_NEXT = (void *)PIKE_CONCAT3(free_,DATA,s); \
fc2c831999-04-01Fredrik Hübinette (Hubbe)  PRE_INIT_BLOCK(d); \ PIKE_CONCAT3(free_,DATA,s)=d; \ } \ \ void PIKE_CONCAT3(free_all_,DATA,_blocks)(void) \ { \ struct PIKE_CONCAT(DATA,_block) *tmp; \
60d9872000-03-23Fredrik Hübinette (Hubbe)  DO_IF_DMALLOC( \ for(tmp=PIKE_CONCAT(DATA,_blocks);tmp;tmp=tmp->next) \ { \ int tmp2; \
111fdd2000-04-17Fredrik Hübinette (Hubbe)  extern void dmalloc_check_block_free(void *p, char *loc); \
60d9872000-03-23Fredrik Hübinette (Hubbe)  for(tmp2=0;tmp2<BSIZE;tmp2++) \
111fdd2000-04-17Fredrik Hübinette (Hubbe)  dmalloc_check_block_free(tmp->x+tmp2, DMALLOC_LOCATION()); \
60d9872000-03-23Fredrik Hübinette (Hubbe)  } \ ) \
fc2c831999-04-01Fredrik Hübinette (Hubbe)  while((tmp=PIKE_CONCAT(DATA,_blocks))) \ { \ PIKE_CONCAT(DATA,_blocks)=tmp->next; \ free((char *)tmp); \ } \ PIKE_CONCAT(DATA,_blocks)=0; \ PIKE_CONCAT3(free_,DATA,s)=0; \ } \
424d9c1999-05-02Fredrik Hübinette (Hubbe)  \ \ void PIKE_CONCAT3(count_memory_in_,DATA,s)(INT32 *num_, INT32 *size_) \ { \ INT32 num=0, size=0; \ struct PIKE_CONCAT(DATA,_block) *tmp; \ struct DATA *tmp2; \ for(tmp=PIKE_CONCAT(DATA,_blocks);tmp;tmp=tmp->next) \ { \ num+=BSIZE; \ size+=sizeof(struct PIKE_CONCAT(DATA,_block)); \
cfa7d82000-01-27Fredrik Hübinette (Hubbe)  COUNT_BLOCK(tmp); \
424d9c1999-05-02Fredrik Hübinette (Hubbe)  } \
011ad31999-10-22Fredrik Hübinette (Hubbe)  for(tmp2=PIKE_CONCAT3(free_,DATA,s);tmp2; \
f87e032000-11-25Henrik Grubbström (Grubba)  tmp2 = (struct DATA *)tmp2->BLOCK_ALLOC_NEXT) num--; \
cfa7d82000-01-27Fredrik Hübinette (Hubbe)  COUNT_OTHER(); \
424d9c1999-05-02Fredrik Hübinette (Hubbe)  *num_=num; \ *size_=size; \ }
fc2c831999-04-01Fredrik Hübinette (Hubbe) 
011ad31999-10-22Fredrik Hübinette (Hubbe) #define PTR_HASH_ALLOC(DATA,BSIZE) \ \ BLOCK_ALLOC(DATA,BSIZE) \ \
3f84322000-04-23Martin Stjernholm struct DATA **PIKE_CONCAT(DATA,_hash_table)=0; \
c7241b2000-08-10Henrik Grubbström (Grubba) ptrdiff_t PIKE_CONCAT(DATA,_hash_table_size)=0; \ static ptrdiff_t PIKE_CONCAT(num_,DATA)=0; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  \ inline struct DATA * \
c7241b2000-08-10Henrik Grubbström (Grubba)  PIKE_CONCAT(really_low_find_,DATA)(void *ptr, ptrdiff_t hval) \
011ad31999-10-22Fredrik Hübinette (Hubbe) { \ struct DATA *p,**pp; \
ec6b782000-03-21Fredrik Hübinette (Hubbe)  p=PIKE_CONCAT(DATA,_hash_table)[hval]; \ if(!p) return 0; \ if(p->data == ptr) return p; \ while((p=*(pp=&p->BLOCK_ALLOC_NEXT))) \
011ad31999-10-22Fredrik Hübinette (Hubbe)  { \ if(p->data==ptr) \ { \ *pp=p->BLOCK_ALLOC_NEXT; \ p->BLOCK_ALLOC_NEXT=PIKE_CONCAT(DATA,_hash_table)[hval]; \ PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ return p; \ } \ } \ return 0; \ } \ \ \ struct DATA *PIKE_CONCAT(find_,DATA)(void *ptr) \ { \
c7241b2000-08-10Henrik Grubbström (Grubba)  size_t hval = (size_t)ptr; \
342fef2000-08-23Fredrik Hübinette (Hubbe)  if(!PIKE_CONCAT(DATA,_hash_table_size)) return 0; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  hval%=PIKE_CONCAT(DATA,_hash_table_size); \ return PIKE_CONCAT(really_low_find_,DATA)(ptr, hval); \ } \ \ \ static void PIKE_CONCAT(DATA,_rehash)() \ { \ /* Time to re-hash */ \ struct DATA **old_hash= PIKE_CONCAT(DATA,_hash_table); \ struct DATA *p; \
c7241b2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t hval; \ ptrdiff_t e=PIKE_CONCAT(DATA,_hash_table_size); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  \ PIKE_CONCAT(DATA,_hash_table_size)*=2; \ PIKE_CONCAT(DATA,_hash_table_size)++; \ if((PIKE_CONCAT(DATA,_hash_table)=(struct DATA **) \ malloc(PIKE_CONCAT(DATA,_hash_table_size)* \ sizeof(struct DATA *)))) \ { \ MEMSET(PIKE_CONCAT(DATA,_hash_table),0, \ sizeof(struct DATA *)*PIKE_CONCAT(DATA,_hash_table_size)); \ while(--e >=0) \ { \ while((p=old_hash[e])) \ { \ old_hash[e]=p->BLOCK_ALLOC_NEXT; \
c7241b2000-08-10Henrik Grubbström (Grubba)  hval=(ptrdiff_t)(p->data); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  hval%=PIKE_CONCAT(DATA,_hash_table_size); \ p->BLOCK_ALLOC_NEXT=PIKE_CONCAT(DATA,_hash_table)[hval]; \ PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ } \ } \ free((char *)old_hash); \ }else{ \ PIKE_CONCAT(DATA,_hash_table)=old_hash; \ PIKE_CONCAT(DATA,_hash_table_size)=e; \ } \ } \ \ \
c7241b2000-08-10Henrik Grubbström (Grubba) struct DATA *PIKE_CONCAT(make_,DATA)(void *ptr, ptrdiff_t hval) \
011ad31999-10-22Fredrik Hübinette (Hubbe) { \ struct DATA *p; \ \ DO_IF_DEBUG( if(!PIKE_CONCAT(DATA,_hash_table)) \
a4a1722000-12-05Per Hedbor  fatal("Hash table error!\n"); ) \
011ad31999-10-22Fredrik Hübinette (Hubbe)  PIKE_CONCAT(num_,DATA)++; \ \ if(( PIKE_CONCAT(num_,DATA)>>2 ) >= \ PIKE_CONCAT(DATA,_hash_table_size)) \ { \ PIKE_CONCAT(DATA,_rehash)(); \
c7241b2000-08-10Henrik Grubbström (Grubba)  hval=(ptrdiff_t)ptr; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  hval%=PIKE_CONCAT(DATA,_hash_table_size); \ } \ \ p=PIKE_CONCAT(alloc_,DATA)(); \ p->data=ptr; \ p->BLOCK_ALLOC_NEXT=PIKE_CONCAT(DATA,_hash_table)[hval]; \ PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ return p; \ } \ \
f3378f2000-05-16Fredrik Hübinette (Hubbe) struct DATA *PIKE_CONCAT(get_,DATA)(void *ptr) \
011ad31999-10-22Fredrik Hübinette (Hubbe) { \ struct DATA *p; \
c7241b2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t hval=(ptrdiff_t)ptr; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  hval%=PIKE_CONCAT(DATA,_hash_table_size); \ if((p=PIKE_CONCAT(really_low_find_,DATA)(ptr, hval))) \ return p; \ \ return PIKE_CONCAT(make_,DATA)(ptr, hval); \ } \ \ int PIKE_CONCAT3(check_,DATA,_semafore)(void *ptr) \ { \ struct DATA *p; \
c7241b2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t hval=(ptrdiff_t)ptr; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  hval%=PIKE_CONCAT(DATA,_hash_table_size); \ if((p=PIKE_CONCAT(really_low_find_,DATA)(ptr, hval))) \ return 0; \ \ PIKE_CONCAT(make_,DATA)(ptr, hval); \ return 1; \ } \ \ int PIKE_CONCAT(remove_,DATA)(void *ptr) \ { \ struct DATA *p; \
c7241b2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t hval=(ptrdiff_t)ptr; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  if(!PIKE_CONCAT(DATA,_hash_table)) return 0; \ hval%=PIKE_CONCAT(DATA,_hash_table_size); \ if((p=PIKE_CONCAT(really_low_find_,DATA)(ptr, hval))) \ { \ PIKE_CONCAT(num_,DATA)--; \ if(PIKE_CONCAT(DATA,_hash_table)[hval]!=p) fatal("GAOssdf\n"); \ PIKE_CONCAT(DATA,_hash_table)[hval]=p->BLOCK_ALLOC_NEXT; \ PIKE_CONCAT(really_free_,DATA)(p); \ return 1; \ } \ return 0; \ } \ \ void PIKE_CONCAT3(init_,DATA,_hash)(void) \ { \ extern INT32 hashprimes[32]; \
9c815b2000-08-10Henrik Grubbström (Grubba)  extern int my_log2(size_t x); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  PIKE_CONCAT(DATA,_hash_table_size)=hashprimes[my_log2(BSIZE)]; \ \ PIKE_CONCAT(DATA,_hash_table)=(struct DATA **) \ malloc(sizeof(struct DATA *)*PIKE_CONCAT(DATA,_hash_table_size)); \ if(!PIKE_CONCAT(DATA,_hash_table)) \ { \ fprintf(stderr,"Fatal: out of memory.\n"); \ exit(17); \ } \ MEMSET(PIKE_CONCAT(DATA,_hash_table),0, \ sizeof(struct DATA *)*PIKE_CONCAT(DATA,_hash_table_size)); \ } \ \ void PIKE_CONCAT3(exit_,DATA,_hash)(void) \ { \ PIKE_CONCAT3(free_all_,DATA,_blocks)(); \ free(PIKE_CONCAT(DATA,_hash_table)); \ PIKE_CONCAT(DATA,_hash_table)=0; \
7bcb1d1999-12-19Fredrik Hübinette (Hubbe)  PIKE_CONCAT(num_,DATA)=0; \
424d9c1999-05-02Fredrik Hübinette (Hubbe) }