GC_key_create (struct tsd * * key_ptr, void (*<Tc6>) (void *) destructor)
{
  int D.4989;
  union pthread_mutex_t * D.4990;
  int i;
  struct tsd * result;

  result = GC_generic_malloc_inner (16424, 1);
  if (result == 0B) goto <D.4987>; else goto <D.4988>;
  <D.4987>:
  D.4989 = 12;
  return D.4989;
  <D.4988>:
  D.4990 = &result->lock;
  pthread_mutex_init (D.4990, 0B);
  i = 0;
  goto <D.4956>;
  <D.4955>:
  result->cache[i] = &invalid_tse;
  i = i + 1;
  <D.4956>:
  if (i <= 1023) goto <D.4955>; else goto <D.4957>;
  <D.4957>:
  *key_ptr = result;
  D.4989 = 0;
  return D.4989;
}


GC_setspecific (struct tsd * key, void * value)
{
  long int self.0;
  long int D.4993;
  int D.4994;
  int D.4995;
  int D.4996;
  int D.4999;
  union pthread_mutex_t * D.5000;
  struct tse * D.5001;
  struct tse *[1024] * D.5002;
  long unsigned int D.5003;
  long unsigned int D.5004;
  volatile struct tse * * D.5005;
  pthread_t self;
  int hash_val;
  volatile struct tse * entry;

  self = pthread_self ();
  self.0 = (long int) self;
  D.4993 = self.0 >> 8;
  D.4994 = (int) D.4993;
  D.4995 = (int) self;
  D.4996 = D.4994 ^ D.4995;
  hash_val = D.4996 & 1023;
  entry = GC_generic_malloc_inner (32, 1);
  if (entry == 0B) goto <D.4997>; else goto <D.4998>;
  <D.4997>:
  D.4999 = 12;
  return D.4999;
  <D.4998>:
  D.5000 = &key->lock;
  pthread_mutex_lock (D.5000);
  D.5001 = key->hash[hash_val];
  entry->next = D.5001;
  entry->thread = self;
  entry->value = value;
  D.5002 = &key->hash;
  D.5003 = (long unsigned int) hash_val;
  D.5004 = D.5003 * 8;
  D.5005 = D.5002 + D.5004;
  *D.5005 = entry;
  D.5000 = &key->lock;
  pthread_mutex_unlock (D.5000);
  D.4999 = 0;
  return D.4999;
}


GC_remove_specific (struct tsd * key)
{
  long int self.1;
  long int D.5008;
  signed int D.5009;
  signed int D.5010;
  signed int D.5011;
  unsigned int D.5012;
  struct tse *[1024] * D.5013;
  long unsigned int D.5014;
  long unsigned int D.5015;
  union pthread_mutex_t * D.5016;
  long unsigned int D.5018;
  struct thread_specific_entry * D.5021;
  pthread_t self;
  unsigned int hash_val;
  struct tse * entry;
  struct tse * * link;

  self = pthread_self ();
  self.1 = (long int) self;
  D.5008 = self.1 >> 8;
  D.5009 = (signed int) D.5008;
  D.5010 = (signed int) self;
  D.5011 = D.5009 ^ D.5010;
  D.5012 = (unsigned int) D.5011;
  hash_val = D.5012 & 1023;
  D.5013 = &key->hash;
  D.5014 = (long unsigned int) hash_val;
  D.5015 = D.5014 * 8;
  link = D.5013 + D.5015;
  D.5016 = &key->lock;
  pthread_mutex_lock (D.5016);
  entry = *link;
  goto <D.4973>;
  <D.4972>:
  link = &entry->next;
  entry = *link;
  <D.4973>:
  if (entry != 0B) goto <D.5017>; else goto <D.4974>;
  <D.5017>:
  D.5018 = entry->thread;
  if (D.5018 != self) goto <D.4972>; else goto <D.4974>;
  <D.4974>:
  entry->qtid = 0;
  if (entry != 0B) goto <D.5019>; else goto <D.5020>;
  <D.5019>:
  D.5021 = entry->next;
  *link = D.5021;
  <D.5020>:
  D.5016 = &key->lock;
  pthread_mutex_unlock (D.5016);
}


GC_slow_getspecific (struct tsd * key, long unsigned int qtid, struct tse * volatile * cache_ptr)
{
  long int self.2;
  long int D.5023;
  signed int D.5024;
  signed int D.5025;
  signed int D.5026;
  unsigned int D.5027;
  long unsigned int D.5029;
  void * D.5032;
  pthread_t self;
  unsigned int hash_val;
  struct tse * entry;

  self = pthread_self ();
  self.2 = (long int) self;
  D.5023 = self.2 >> 8;
  D.5024 = (signed int) D.5023;
  D.5025 = (signed int) self;
  D.5026 = D.5024 ^ D.5025;
  D.5027 = (unsigned int) D.5026;
  hash_val = D.5027 & 1023;
  entry = key->hash[hash_val];
  goto <D.4984>;
  <D.4983>:
  entry = entry->next;
  <D.4984>:
  if (entry != 0B) goto <D.5028>; else goto <D.4985>;
  <D.5028>:
  D.5029 = entry->thread;
  if (D.5029 != self) goto <D.4983>; else goto <D.4985>;
  <D.4985>:
  if (entry == 0B) goto <D.5030>; else goto <D.5031>;
  <D.5030>:
  D.5032 = 0B;
  return D.5032;
  <D.5031>:
  entry->qtid = qtid;
  *cache_ptr = entry;
  D.5032 = entry->value;
  return D.5032;
}


