Exemple #1
0
/*
  Put pins back to a pinbox. Usually called via lf_alloc_put_pins() or
  lf_hash_put_pins().

  DESCRIPTION
    empty the purgatory (XXX deadlock warning below!),
    push LF_PINS structure to a stack
*/
void _lf_pinbox_put_pins(LF_PINS *pins)
{
  LF_PINBOX *pinbox= pins->pinbox;
  uint32 top_ver, nr;
  nr= pins->link;

#ifndef DBUG_OFF
  {
    /* This thread should not hold any pin. */
    int i;
    for (i= 0; i < LF_PINBOX_PINS; i++)
      DBUG_ASSERT(pins->pin[i] == 0);
  }
#endif /* DBUG_OFF */

  /*
    XXX this will deadlock if other threads will wait for
    the caller to do something after _lf_pinbox_put_pins(),
    and they would have pinned addresses that the caller wants to free.
    Thus: only free pins when all work is done and nobody can wait for you!!!
  */
  while (pins->purgatory_count)
  {
    _lf_pinbox_real_free(pins);
    if (pins->purgatory_count)
    {
      my_atomic_rwlock_wrunlock(&pins->pinbox->pinarray.lock);
      pthread_yield();
      my_atomic_rwlock_wrlock(&pins->pinbox->pinarray.lock);
    }
  }
  top_ver= pinbox->pinstack_top_ver;
  do
  {
    pins->link= top_ver % LF_PINBOX_MAX_PINS;
  } while (!my_atomic_cas32((int32 volatile*) &pinbox->pinstack_top_ver,
                            (int32*) &top_ver,
                            top_ver-pins->link+nr+LF_PINBOX_MAX_PINS));
  return;
}
/*
  Free an object allocated via pinbox allocator

  DESCRIPTION
    add an object to purgatory. if necessary, call _lf_pinbox_real_free()
    to actually free something.
*/
void _lf_pinbox_free(LF_PINS *pins, void *addr)
{
  add_to_purgatory(pins, addr);
  if (pins->purgatory_count % LF_PURGATORY_SIZE)
    _lf_pinbox_real_free(pins);
}