コード例 #1
0
ファイル: slab.cpp プロジェクト: B-Rich/NOVA
void Slab_cache::free (void *ptr)
{
    Lock_guard <Spinlock> guard (lock);

    Slab *slab = reinterpret_cast<Slab *>(reinterpret_cast<mword>(ptr) & ~PAGE_MASK);

    bool was_full = slab->full();

    slab->free (ptr);       // Deallocate from slab

    if (EXPECT_FALSE (was_full)) {

        // There are full slabs in front of us and we're partial; requeue
        if (slab->prev && slab->prev->full()) {

            // Dequeue
            slab->prev->next = slab->next;
            if (slab->next)
                slab->next->prev = slab->prev;

            // Enqueue after curr
            if (curr) {
                slab->prev = curr;
                slab->next = curr->next;
                curr->next = curr->next->prev = slab;
            }

            // Enqueue as head
            else {
                slab->prev = nullptr;
                slab->next = head;
                head = head->prev = slab;
            }
        }

        curr = slab;

    } else if (EXPECT_FALSE (slab->empty())) {

        // There are partial slabs in front of us and we're empty; requeue
        if (slab->prev && !slab->prev->empty()) {

            // Make partial slab in front of us current if we were current
            if (slab == curr)
                curr = slab->prev;

            // Dequeue
            slab->prev->next = slab->next;
            if (slab->next)
                slab->next->prev = slab->prev;

            // Enqueue as head
            slab->prev = nullptr;
            slab->next = head;
            head = head->prev = slab;
        }
    }
}
コード例 #2
0
ファイル: slab_cache.cpp プロジェクト: laborjack/L4Re
PUBLIC
void
Slab_cache::free(void *cache_entry) // return initialized member to cache
{
  Slab *to_free = 0;
    {
      auto guard = lock_guard(lock);

      Slab *s = reinterpret_cast<Slab*>
	((reinterpret_cast<unsigned long>(cache_entry) & ~(_slab_size - 1)) + _slab_size - sizeof(Slab));

      bool was_full = s->is_full();

      s->free(cache_entry);

      if (was_full)
	{
	  cxx::H_list<Slab>::remove(s);
	  _partial.add(s);
	}
      else if (s->is_empty())
	{
	  cxx::H_list<Slab>::remove(s);
	  if (_num_empty < 2)
	    {
	      _empty.add(s);
	      ++_num_empty;
	    }
	  else
	    to_free = s;
	}
      else
	{
	  // We weren't either full or empty; we already had free
	  // elements.  This changes nothing in the queue, and there
	  // already must have been a _first_available_slab.
	}
    }

  if (to_free)
    {
      to_free->~Slab();
      block_free(reinterpret_cast<char *>(to_free + 1) - _slab_size, _slab_size);
    }
}