pike.git / src / stralloc.c

version» Context lines:

pike.git/src/stralloc.c:19:      #include <errno.h>   #include <float.h>   #include <ctype.h>   #include <math.h>      #ifndef HUGE   #define HUGE HUGE_VAL   #endif /*!HUGE*/    - RCSID("$Id: stralloc.c,v 1.121 2001/03/30 09:09:09 hubbe Exp $"); + RCSID("$Id: stralloc.c,v 1.122 2001/03/30 12:23:16 hubbe Exp $");      #if PIKE_RUN_UNLOCKED -  + /* Make this bigger when we get lightweight threads */ + #define BUCKET_LOCKS 2048   static PIKE_MUTEX_T *bucket_locks;    - #define LOCK_BUCKET(HVAL) do { \ -  size_t hval__=(HVAL); \ -  PIKE_MUTEX_T *bucket_lock; \ -  while(1) \ -  { \ -  bucket_lock=bucket_locks + (hval__ % htable_size); \ -  mt_lock(bucket_lock); \ -  if(bucket_lock == bucket_locks + (hval__ % htable_size)) \ -  break; \ -  mt_unlock(bucket_lock); \ -  } \ + #define BUCKETLOCK(HVAL) \ +  (bucket_locks + ((hval__ % htable_size) & (BUCKET_LOCKS-1))) +  + #define LOCK_BUCKET(HVAL) do { \ +  size_t hval__=(HVAL); \ +  PIKE_MUTEX_T *bucket_lock; \ +  while(1) \ +  { \ +  bucket_lock=BUCKETLOCK(hval__); \ +  mt_lock(bucket_lock); \ +  if(bucket_lock == BUCKETLOCK(hval__)) \ +  break; \ +  mt_unlock(bucket_lock); \ +  } \   }while(0)      #define UNLOCK_BUCKET(HVAL) do { \    size_t hval__=(HVAL); \ -  mt_unlock(bucket_locks + ( hval__ % htable_size )); \ +  mt_unlock(BUCKETLOCK(hval__)); \   }while(0)      #else   #define LOCK_BUCKET(HVAL)   #define UNLOCK_BUCKET(HVAL)   #endif      #define BEGIN_HASH_SIZE 997   #define MAX_AVG_LINK_LENGTH 3   
pike.git/src/stralloc.c:424:    h = s->hval % htable_size;    s->next=base_table[h];    base_table[h]=s;   }      static void stralloc_rehash(void)   {    int h,old;    struct pike_string **old_base;    - #ifdef PIKE_RUN_UNLOCKED -  int new_htable_size; -  PIKE_MUTEX_T *old_locks; -  PIKE_MUTEX_T *new_locks; -  +     old=htable_size;    old_base=base_table;    -  LOCK_BUCKET(0); + #ifdef PIKE_RUN_UNLOCKED +  mt_lock(bucket_locks);    if(old != htable_size)    {    /* Someone got here before us */ -  UNLOCK_BUCKET(0); +  mt_lock(bucket_locks);    return;    }    -  new_htable_size=hashprimes[++hashprimes_entry]; -  +     /* Now that we have bucket zero, the hash table    * cannot change, go ahead and lock ALL buckets.    * NOTE: bucket zero is already locked    */ -  for(h=1;h<old;h++) LOCK_BUCKET(h); -  new_locks=(PIKE_MUTEX_T *)xalloc(sizeof(PIKE_MUTEX_T)*new_htable_size); -  for(h=0;h<new_htable_size;h++) -  { -  mt_init(new_locks + h); -  mt_lock(new_locks + h); -  } -  old_locks=bucket_locks; -  bucket_locks=new_locks; -  htable_size=new_htable_size; - #else -  old=htable_size; -  old_base=base_table; +  for(h=1;h<BUCKET_LOCKS;h++) mt_lock(bucket_locks+h); + #endif       htable_size=hashprimes[++hashprimes_entry]; - #endif +        base_table=(struct pike_string **)xalloc(sizeof(struct pike_string *)*htable_size);    MEMSET((char *)base_table,0,sizeof(struct pike_string *)*htable_size);       for(h=0;h<old;h++)    rehash_string_backwards(old_base[h]);       if(old_base)    free((char *)old_base);      #ifdef PIKE_RUN_UNLOCKED -  for(h=0;h<old;h++) mt_unlock(old_locks + h); -  for(h=0;h<htable_size;h++) mt_unlock(new_locks + h); -  -  -  /* This loop tries to make sure that nobody is still waiting -  * for the old locks. I'm not sure if it actually works 100% of -  * the time though... /Hubbe -  */ -  for(h=0;h<old;h++) -  { -  mt_lock(old_locks + h); -  mt_unlock(old_locks + h); -  mt_destroy(old_locks+h); -  } -  free((char *)old_locks); +  for(h=0;h<BUCKET_LOCKS;h++) mt_unlock(bucket_locks + h);   #endif   }      /* Allocation of strings */      /* Allocate some fixed string sizes with BLOCK_ALLOC. */      /* Use the BLOCK_ALLOC() stuff for short strings */      #define SHORT_STRING_BLOCK 256
pike.git/src/stralloc.c:592:    stralloc_rehash();      #ifndef HASH_PREFIX    /* These heuruistics might require tuning! /Hubbe */    if(need_more_hash_prefix > ( htable_size >> 4))    {    /* This could in theory have a pretty ugly complexity */    /* /Hubbe    */    + #ifdef PIKE_RUN_UNLOCKED +  mt_lock(bucket_locks); +  if(need_more_hash_prefix <= ( htable_size >> 4)) +  { +  /* Someone got here before us */ +  mt_lock(bucket_locks); +  return; +  } +  for(h=1;h<BUCKET_LOCKS;h++) mt_lock(bucket_locks+h); + #endif +     need_more_hash_prefix=0;    HASH_PREFIX=HASH_PREFIX*2;   /* fprintf(stderr,"Doubling HASH_PREFIX to %d and rehashing\n",HASH_PREFIX); */       for(h=0;h<htable_size;h++)    {    struct pike_string *tmp=base_table[h];    base_table[h]=0;    while(tmp)    {
pike.git/src/stralloc.c:613: Inside #if undefined(HASH_PREFIX)
   struct pike_string *tmp2=tmp; /* First unlink */    tmp=tmp2->next;       tmp2->hval=do_hash(tmp2); /* compute new hash value */    h2=tmp2->hval % htable_size;       tmp2->next=base_table[h2]; /* and re-hash */    base_table[h2]=tmp2;    }    } + #ifdef PIKE_RUN_UNLOCKED +  for(h=0;h<BUCKET_LOCKS;h++) mt_unlock(bucket_locks + h); + #endif    }   #endif   }      PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, int shift)   {    struct pike_string *t;   #ifdef PIKE_DEBUG    extern int d_flag;    if(d_flag>10)
pike.git/src/stralloc.c:1763:    init_short_pike_string0_blocks();    init_short_pike_string1_blocks();    init_short_pike_string2_blocks();    for(hashprimes_entry=0;hashprimes[hashprimes_entry]<BEGIN_HASH_SIZE;hashprimes_entry++);    htable_size=hashprimes[hashprimes_entry];    base_table=(struct pike_string **)xalloc(sizeof(struct pike_string *)*htable_size);    MEMSET((char *)base_table,0,sizeof(struct pike_string *)*htable_size);   #ifdef PIKE_RUN_UNLOCKED    {    int h; -  bucket_locks=(PIKE_MUTEX_T *)xalloc(sizeof(PIKE_MUTEX_T)*htable_size); -  for(h=0;h<htable_size;h++) mt_init(bucket_locks + h); +  bucket_locks=(PIKE_MUTEX_T *)xalloc(sizeof(PIKE_MUTEX_T)*BUCKET_LOCKS); +  for(h=0;h<BUCKET_LOCKS;h++) mt_init(bucket_locks + h);    }   #endif   }      #ifdef DEBUG_MALLOC   struct shared_string_location *all_shared_string_locations;   #endif         void cleanup_shared_string_table(void)