e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
1b10db2002-10-08Martin Nilsson 
4218011999-01-31Fredrik Hübinette (Hubbe) #undef INIT_BLOCK #undef EXIT_BLOCK #undef BLOCK_ALLOC
afbc722001-09-06Fredrik Hübinette (Hubbe) #undef LOW_PTR_HASH_ALLOC #undef PTR_HASH_ALLOC_FIXED
fc2c831999-04-01Fredrik Hübinette (Hubbe) #undef PTR_HASH_ALLOC
7d63aa2001-11-08Fredrik Hübinette (Hubbe) #undef BLOCK_ALLOC_HSIZE_SHIFT
db1aac2002-11-24Martin Stjernholm #undef BLOCK_ALLOC_FILL_PAGES #undef PTR_HASH_ALLOC_FILL_PAGES #undef PTR_HASH_ALLOC_FIXED_FILL_PAGES
4218011999-01-31Fredrik Hübinette (Hubbe) 
84874e2008-05-24Martin Stjernholm /* Define this to keep freed blocks around in a backlog, which can * help locating leftover pointers to other blocks. It can also hide * bugs since the blocks remain intact a while after they are freed. * Valgrind will immediately detect attempts to use blocks on the * backlog list, though. Only available with dmalloc debug. */ /* #define DMALLOC_BLOCK_BACKLOG */
21ed0e1998-02-19Fredrik Hübinette (Hubbe) #define INIT_BLOCK(X) #define EXIT_BLOCK(X)
7d63aa2001-11-08Fredrik Hübinette (Hubbe) #define BLOCK_ALLOC_HSIZE_SHIFT 2
4218011999-01-31Fredrik Hübinette (Hubbe) 
84874e2008-05-24Martin Stjernholm #if defined (DMALLOC_BLOCK_BACKLOG) && defined (DEBUG_MALLOC) #define DO_IF_BLOCK_BACKLOG(X) X
fd9dd52008-05-24Martin Stjernholm #define DO_IF_NOT_BLOCK_BACKLOG(X)
cd013b2009-04-25Martin Stjernholm #define BLOCK_ALLOC_USED real_used
84874e2008-05-24Martin Stjernholm #else #define DO_IF_BLOCK_BACKLOG(X)
fd9dd52008-05-24Martin Stjernholm #define DO_IF_NOT_BLOCK_BACKLOG(X) X
cd013b2009-04-25Martin Stjernholm #define BLOCK_ALLOC_USED used
84874e2008-05-24Martin Stjernholm #endif
c473222003-02-24Henrik Grubbström (Grubba) #ifndef PIKE_HASH_T
322f892003-03-16Henrik Grubbström (Grubba) #define PIKE_HASH_T size_t
c473222003-02-24Henrik Grubbström (Grubba) #endif /* !PIKE_HASH_T */
aad99b2001-03-28Fredrik Hübinette (Hubbe) #ifdef PIKE_RUN_UNLOCKED #include "threads.h"
b076ce2001-08-31Fredrik Hübinette (Hubbe)  /* Block Alloc UnLocked */ #define BA_UL(X) PIKE_CONCAT(X,_unlocked) #define BA_STATIC static
54a1302004-06-02Martin Nilsson #define BA_INLINE INLINE
b076ce2001-08-31Fredrik Hübinette (Hubbe) #else #define BA_UL(X) X #define BA_STATIC
0f5ac12001-09-02Henrik Grubbström (Grubba) #define BA_INLINE
aad99b2001-03-28Fredrik Hübinette (Hubbe) #endif
db1aac2002-11-24Martin Stjernholm  #define PTR_HASH_ALLOC_FILL_PAGES(DATA, PAGES) \ PTR_HASH_ALLOC(DATA, \ ((PIKE_MALLOC_PAGE_SIZE * (PAGES)) \ - PIKE_MALLOC_OVERHEAD - BLOCK_HEADER_SIZE) / \ sizeof (struct DATA)) #define PTR_HASH_ALLOC_FIXED_FILL_PAGES(DATA, PAGES) \ PTR_HASH_ALLOC_FIXED(DATA, \ ((PIKE_MALLOC_PAGE_SIZE * (PAGES)) \ - PIKE_MALLOC_OVERHEAD - BLOCK_HEADER_SIZE) / \ sizeof (struct DATA)) /* Size of the members in the block struct below that don't contain * the payload data (i.e. that aren't x). This can be used in BSIZE to * make the block fit within a page. */ #ifndef BLOCK_HEADER_SIZE
46ff8a2008-08-26Henrik Grubbström (Grubba) #define BLOCK_HEADER_SIZE (3 * sizeof (void *) + sizeof (INT32) \ DO_IF_DMALLOC( + sizeof(INT32)))
db1aac2002-11-24Martin Stjernholm #endif
99b5ff2002-11-24Martin Stjernholm 
63150e2005-04-08Henrik Grubbström (Grubba) }
fc2c831999-04-01Fredrik Hübinette (Hubbe) 
a8dfaa2013-10-09Arne Goedeke #include "block_allocator.h"
fc2c831999-04-01Fredrik Hübinette (Hubbe) 
afbc722001-09-06Fredrik Hübinette (Hubbe) #define LOW_PTR_HASH_ALLOC(DATA,BSIZE) \
011ad31999-10-22Fredrik Hübinette (Hubbe)  \
a8dfaa2013-10-09Arne Goedeke static struct block_allocator PIKE_CONCAT(DATA,_allocator) = \ BA_INIT(sizeof(struct DATA), BSIZE); \ \ struct DATA *PIKE_CONCAT(alloc_,DATA)(void) { \ struct DATA * ptr = (struct DATA *)ba_alloc(&PIKE_CONCAT(DATA,_allocator));\ INIT_BLOCK(ptr); \ return ptr; \ } \ \ void PIKE_CONCAT(really_free_,DATA)(struct DATA *d) { \ EXIT_BLOCK(d); \ ba_free(&PIKE_CONCAT(DATA,_allocator), d); \ } \ \ void PIKE_CONCAT3(count_memory_in_,DATA,s)(size_t *num_, size_t *size_) { \ ba_count_all(&PIKE_CONCAT(DATA,_allocator), num_, size_); \ } \
011ad31999-10-22Fredrik Hübinette (Hubbe)  \
3f84322000-04-23Martin Stjernholm struct DATA **PIKE_CONCAT(DATA,_hash_table)=0; \
59e0112001-07-03Fredrik Hübinette (Hubbe) size_t PIKE_CONCAT(DATA,_hash_table_size)=0; \
afbc722001-09-06Fredrik Hübinette (Hubbe) size_t PIKE_CONCAT(DATA,_hash_table_magnitude)=0; \
b0a2362002-12-01Martin Stjernholm static size_t PIKE_CONCAT(num_,DATA)=0; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  \
54a1302004-06-02Martin Nilsson static INLINE struct DATA * \
c473222003-02-24Henrik Grubbström (Grubba)  PIKE_CONCAT3(really_low_find_,DATA,_unlocked)(void *ptr, \ PIKE_HASH_T hval) \
011ad31999-10-22Fredrik Hübinette (Hubbe) { \
d856cf2013-06-12Arne Goedeke  struct DATA *p; \
ec6b782000-03-21Fredrik Hübinette (Hubbe)  p=PIKE_CONCAT(DATA,_hash_table)[hval]; \
db1aac2002-11-24Martin Stjernholm  if(!p || p->PTR_HASH_ALLOC_DATA == ptr) \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  { \ return p; \ } \
d856cf2013-06-12Arne Goedeke  while((p=p->BLOCK_ALLOC_NEXT)) \
011ad31999-10-22Fredrik Hübinette (Hubbe)  { \
db1aac2002-11-24Martin Stjernholm  if(p->PTR_HASH_ALLOC_DATA==ptr) \
011ad31999-10-22Fredrik Hübinette (Hubbe)  { \ return p; \ } \ } \ return 0; \ } \ \ struct DATA *PIKE_CONCAT(find_,DATA)(void *ptr) \ { \
805f812001-03-30Fredrik Hübinette (Hubbe)  struct DATA *p; \
d2361e2003-06-30Martin Stjernholm  PIKE_HASH_T hval = (PIKE_HASH_T)PTR_TO_INT(ptr); \
805f812001-03-30Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \
949ecb2006-03-10Martin Stjernholm  if(!PIKE_CONCAT(DATA,_hash_table)) { \
805f812001-03-30Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ return 0; \ } \
c473222003-02-24Henrik Grubbström (Grubba)  hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
805f812001-03-30Fredrik Hübinette (Hubbe)  p=PIKE_CONCAT3(really_low_find_,DATA,_unlocked)(ptr, hval); \ DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ return p; \
011ad31999-10-22Fredrik Hübinette (Hubbe) } \ \
54a1302004-06-02Martin Nilsson static INLINE struct DATA * \
c2b2442003-03-16Henrik Grubbström (Grubba)  PIKE_CONCAT3(just_find_,DATA,_unlocked)(void *ptr, \ PIKE_HASH_T hval) \ { \
1abbfb2006-07-05Martin Stjernholm  struct DATA *p; \
c2b2442003-03-16Henrik Grubbström (Grubba)  p=PIKE_CONCAT(DATA,_hash_table)[hval]; \ if(!p || p->PTR_HASH_ALLOC_DATA == ptr) \ { \ return p; \ } \ while((p=p->BLOCK_ALLOC_NEXT)) \ { \ if(p->PTR_HASH_ALLOC_DATA==ptr) return p; \ } \ return 0; \ } \ \ static struct DATA *PIKE_CONCAT(just_find_,DATA)(void *ptr) \ { \ struct DATA *p; \
d2361e2003-06-30Martin Stjernholm  PIKE_HASH_T hval = (PIKE_HASH_T)PTR_TO_INT(ptr); \
c2b2442003-03-16Henrik Grubbström (Grubba)  DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \
949ecb2006-03-10Martin Stjernholm  if(!PIKE_CONCAT(DATA,_hash_table)) { \
c2b2442003-03-16Henrik Grubbström (Grubba)  DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ return 0; \ } \ hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \ p=PIKE_CONCAT3(just_find_,DATA,_unlocked)(ptr, hval); \ DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ return p; \ } \ \
011ad31999-10-22Fredrik Hübinette (Hubbe)  \
805f812001-03-30Fredrik Hübinette (Hubbe)  \
d77bd52002-12-01Martin Stjernholm struct DATA *PIKE_CONCAT(make_,DATA)(void *ptr) \
805f812001-03-30Fredrik Hübinette (Hubbe) { \ struct DATA *p; \
d2361e2003-06-30Martin Stjernholm  PIKE_HASH_T hval = (PIKE_HASH_T)PTR_TO_INT(ptr); \
805f812001-03-30Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \
c473222003-02-24Henrik Grubbström (Grubba)  hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
805f812001-03-30Fredrik Hübinette (Hubbe)  p=PIKE_CONCAT3(make_,DATA,_unlocked)(ptr,hval); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  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; \
d2361e2003-06-30Martin Stjernholm  PIKE_HASH_T hval = (PIKE_HASH_T)PTR_TO_INT(ptr); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \
c473222003-02-24Henrik Grubbström (Grubba)  hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
805f812001-03-30Fredrik Hübinette (Hubbe)  if(!(p=PIKE_CONCAT3(really_low_find_,DATA,_unlocked)(ptr, hval))) \ p=PIKE_CONCAT3(make_,DATA,_unlocked)(ptr, hval); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ return p; \
011ad31999-10-22Fredrik Hübinette (Hubbe) } \ \
e921e72008-01-24Henrik Grubbström (Grubba) int PIKE_CONCAT3(check_,DATA,_semaphore)(void *ptr) \
011ad31999-10-22Fredrik Hübinette (Hubbe) { \
d2361e2003-06-30Martin Stjernholm  PIKE_HASH_T hval = (PIKE_HASH_T)PTR_TO_INT(ptr); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \
c473222003-02-24Henrik Grubbström (Grubba)  hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
e921e72008-01-24Henrik Grubbström (Grubba)  if(PIKE_CONCAT3(really_low_find_,DATA,_unlocked)(ptr, hval)) \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  { \ DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  return 0; \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  } \
011ad31999-10-22Fredrik Hübinette (Hubbe)  \
805f812001-03-30Fredrik Hübinette (Hubbe)  PIKE_CONCAT3(make_,DATA,_unlocked)(ptr, hval); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  return 1; \ } \ \
e13e712002-12-01Martin Stjernholm void PIKE_CONCAT(move_,DATA)(struct DATA *block, void *new_ptr) \ { \
d856cf2013-06-12Arne Goedeke  struct DATA **pp, *p; \
c473222003-02-24Henrik Grubbström (Grubba)  PIKE_HASH_T hval = \
d2361e2003-06-30Martin Stjernholm  (PIKE_HASH_T)PTR_TO_INT(block->PTR_HASH_ALLOC_DATA); \
e13e712002-12-01Martin Stjernholm  DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \
c473222003-02-24Henrik Grubbström (Grubba)  hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
d856cf2013-06-12Arne Goedeke  pp=PIKE_CONCAT(DATA,_hash_table) + hval; \ while((p = *pp)) \ { \ if(p == block) \ { \ *pp = p->BLOCK_ALLOC_NEXT; \ break; \ } \ pp = &p->BLOCK_ALLOC_NEXT; \ } \ if (!p) Pike_fatal("The block to move wasn't found.\n"); \
e13e712002-12-01Martin Stjernholm  block->PTR_HASH_ALLOC_DATA = new_ptr; \
d2361e2003-06-30Martin Stjernholm  hval = (PIKE_HASH_T)PTR_TO_INT(new_ptr) % \
c473222003-02-24Henrik Grubbström (Grubba)  (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
e13e712002-12-01Martin Stjernholm  block->BLOCK_ALLOC_NEXT = PIKE_CONCAT(DATA,_hash_table)[hval]; \ PIKE_CONCAT(DATA,_hash_table)[hval] = block; \ DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ } \ \
011ad31999-10-22Fredrik Hübinette (Hubbe) int PIKE_CONCAT(remove_,DATA)(void *ptr) \ { \
d856cf2013-06-12Arne Goedeke  struct DATA **pp, *p; \
d2361e2003-06-30Martin Stjernholm  PIKE_HASH_T hval = (PIKE_HASH_T)PTR_TO_INT(ptr); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \ if(!PIKE_CONCAT(DATA,_hash_table)) \ { \ DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ return 0; \ } \
c473222003-02-24Henrik Grubbström (Grubba)  hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
d856cf2013-06-12Arne Goedeke  pp=PIKE_CONCAT(DATA,_hash_table) + hval; \ while((p = *pp)) \
011ad31999-10-22Fredrik Hübinette (Hubbe)  { \
d856cf2013-06-12Arne Goedeke  if(p->PTR_HASH_ALLOC_DATA==ptr) \ { \ *pp = p->BLOCK_ALLOC_NEXT; \ PIKE_CONCAT(num_,DATA)--; \ BA_UL(PIKE_CONCAT(really_free_,DATA))(p); \ DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ return 1; \ } \ pp = &p->BLOCK_ALLOC_NEXT; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  } \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  return 0; \ } \ \
b0a2362002-12-01Martin Stjernholm void PIKE_CONCAT3(low_init_,DATA,_hash)(size_t size) \
011ad31999-10-22Fredrik Hübinette (Hubbe) { \
fc60d42004-06-01Martin Nilsson  extern const INT32 hashprimes[32]; \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  extern int my_log2(size_t x); \ PIKE_CONCAT3(init_,DATA,_blocks)(); \ DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \
afbc722001-09-06Fredrik Hübinette (Hubbe)  PIKE_CONCAT(DATA,_hash_table_size)= \ hashprimes[PIKE_CONCAT(DATA,_hash_table_magnitude)=my_log2(size)]; \
011ad31999-10-22Fredrik Hübinette (Hubbe)  \ 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)); \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \
011ad31999-10-22Fredrik Hübinette (Hubbe) } \ \
afbc722001-09-06Fredrik Hübinette (Hubbe)  \ void PIKE_CONCAT3(init_,DATA,_hash)(void) \ { \ PIKE_CONCAT3(low_init_,DATA,_hash)(BSIZE); \ } \ \
011ad31999-10-22Fredrik Hübinette (Hubbe) void PIKE_CONCAT3(exit_,DATA,_hash)(void) \ { \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \
a8dfaa2013-10-09Arne Goedeke  ba_free_all(& PIKE_CONCAT(DATA,_allocator)); \
011ad31999-10-22Fredrik Hübinette (Hubbe)  free(PIKE_CONCAT(DATA,_hash_table)); \ PIKE_CONCAT(DATA,_hash_table)=0; \
7bcb1d1999-12-19Fredrik Hübinette (Hubbe)  PIKE_CONCAT(num_,DATA)=0; \
aad99b2001-03-28Fredrik Hübinette (Hubbe)  DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \
424d9c1999-05-02Fredrik Hübinette (Hubbe) }
afbc722001-09-06Fredrik Hübinette (Hubbe)  #define PTR_HASH_ALLOC_FIXED(DATA,BSIZE) \
d037172003-02-24Henrik Grubbström (Grubba) struct DATA *PIKE_CONCAT3(make_,DATA,_unlocked)(void *ptr, PIKE_HASH_T hval);\
afbc722001-09-06Fredrik Hübinette (Hubbe) LOW_PTR_HASH_ALLOC(DATA,BSIZE) \ \
d037172003-02-24Henrik Grubbström (Grubba) struct DATA *PIKE_CONCAT3(make_,DATA,_unlocked)(void *ptr, PIKE_HASH_T hval) \
afbc722001-09-06Fredrik Hübinette (Hubbe) { \ struct DATA *p; \ \ DO_IF_DEBUG( if(!PIKE_CONCAT(DATA,_hash_table)) \
b0a2362002-12-01Martin Stjernholm  Pike_fatal("Hash table error!\n"); ) \
afbc722001-09-06Fredrik Hübinette (Hubbe)  PIKE_CONCAT(num_,DATA)++; \ \ p=BA_UL(PIKE_CONCAT(alloc_,DATA))(); \
db1aac2002-11-24Martin Stjernholm  p->PTR_HASH_ALLOC_DATA=ptr; \
afbc722001-09-06Fredrik Hübinette (Hubbe)  p->BLOCK_ALLOC_NEXT=PIKE_CONCAT(DATA,_hash_table)[hval]; \ PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ return p; \
63150e2005-04-08Henrik Grubbström (Grubba) }
afbc722001-09-06Fredrik Hübinette (Hubbe)  #define PTR_HASH_ALLOC(DATA,BSIZE) \
bee7632003-02-24Henrik Grubbström (Grubba) struct DATA *PIKE_CONCAT3(make_,DATA,_unlocked)(void *ptr, \ PIKE_HASH_T hval); \
afbc722001-09-06Fredrik Hübinette (Hubbe) LOW_PTR_HASH_ALLOC(DATA,BSIZE) \ \
0ca86e2005-04-09Henrik Grubbström (Grubba) static void PIKE_CONCAT(DATA,_rehash)(void) \
afbc722001-09-06Fredrik Hübinette (Hubbe) { \ /* Time to re-hash */ \
fc60d42004-06-01Martin Nilsson  extern const INT32 hashprimes[32]; \
afbc722001-09-06Fredrik Hübinette (Hubbe)  struct DATA **old_hash; \ struct DATA *p; \
c473222003-02-24Henrik Grubbström (Grubba)  PIKE_HASH_T hval; \
afbc722001-09-06Fredrik Hübinette (Hubbe)  size_t e; \ \ old_hash= PIKE_CONCAT(DATA,_hash_table); \ e=PIKE_CONCAT(DATA,_hash_table_size); \ \ PIKE_CONCAT(DATA,_hash_table_magnitude)++; \ PIKE_CONCAT(DATA,_hash_table_size)= \ hashprimes[PIKE_CONCAT(DATA,_hash_table_magnitude)]; \ 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; \
d2361e2003-06-30Martin Stjernholm  hval = (PIKE_HASH_T)PTR_TO_INT(p->PTR_HASH_ALLOC_DATA); \
c473222003-02-24Henrik Grubbström (Grubba)  hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
afbc722001-09-06Fredrik Hübinette (Hubbe)  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; \ } \ } \ \
c473222003-02-24Henrik Grubbström (Grubba) struct DATA *PIKE_CONCAT3(make_,DATA,_unlocked)(void *ptr, \ PIKE_HASH_T hval) \
afbc722001-09-06Fredrik Hübinette (Hubbe) { \ struct DATA *p; \ \ DO_IF_DEBUG( if(!PIKE_CONCAT(DATA,_hash_table)) \
b0a2362002-12-01Martin Stjernholm  Pike_fatal("Hash table error!\n"); ) \
afbc722001-09-06Fredrik Hübinette (Hubbe)  PIKE_CONCAT(num_,DATA)++; \ \
7d63aa2001-11-08Fredrik Hübinette (Hubbe)  if(( PIKE_CONCAT(num_,DATA)>>BLOCK_ALLOC_HSIZE_SHIFT ) >= \
afbc722001-09-06Fredrik Hübinette (Hubbe)  PIKE_CONCAT(DATA,_hash_table_size)) \ { \ PIKE_CONCAT(DATA,_rehash)(); \
d2361e2003-06-30Martin Stjernholm  hval = (PIKE_HASH_T)PTR_TO_INT(ptr); \
c473222003-02-24Henrik Grubbström (Grubba)  hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \
afbc722001-09-06Fredrik Hübinette (Hubbe)  } \ \ p=BA_UL(PIKE_CONCAT(alloc_,DATA))(); \
db1aac2002-11-24Martin Stjernholm  p->PTR_HASH_ALLOC_DATA=ptr; \
afbc722001-09-06Fredrik Hübinette (Hubbe)  p->BLOCK_ALLOC_NEXT=PIKE_CONCAT(DATA,_hash_table)[hval]; \ PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ return p; \
1f5f6a2001-09-08Henrik Grubbström (Grubba) }