// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <fbl/algorithm.h>
#include <fbl/auto_lock.h>
#include <fbl/deleter.h>
#include <fbl/intrusive_single_list.h>
#include <fbl/mutex.h>
#include <fbl/null_lock.h>
#include <fbl/ref_ptr.h>
#include <fbl/slab_malloc.h>
#include <fbl/type_support.h>
#include <fbl/unique_ptr.h>
#include <new>
#include <type_traits>
#include <utility>
#include <zircon/compiler.h>

// Usage Notes:
//
// fbl::SlabAllocator<> is a utility class which implements a slab-style
// allocator for a given object type.  It can be used to dispense either managed
// or unmanaged pointer types.  Managed pointers automatically return to the
// allocator when they go completely out of scope, while unmanaged pointers must
// be manually returned to the allocator they came from.  Allocators may be
// "static" (meaning that there is only one allocator for the type for the
// entire process), or "instanced" meaning that there may be multiple instances
// of the allocator for the type, each with independent quotas.
//
// :: SlabAllocatorTraits<> ::
// The properties and behavior of a type of slab allocator is controlled using
// the SlabAllocatorTraits<> struct.  Things which can be controlled include...
//
// ++ The type of object and pointer created by the allocator.
// ++ The size of the slabs of memory which get allocated.
// ++ The synchronization primitive used to achieve thread safety.
// ++ The static/instanced/manual-delete nature of the allocator.
//
// Details on each of these items are included in the sections below.
//
// :: Memory limits and allocation behavior ::
//
// Slab allocators allocate large regions of memory (slabs) and carve them into
// properly aligned regions just large enough to hold an instance of the
// allocator's object type.  Internally, the allocator maintains a list of the
// slabs it has allocated as well as a free list of currently unused blocks of
// object memory.
//
// When allocations are performed...
// 1) Objects from the free list are used first.
// 2) If the free list is empty and the currently active slab has not been
//    completely used, a block of object memory is taken from the currently
//    active slab.
// 3) If the currently active slab has no more space, and the slab allocation
//    limit has not been reached, a new slab will be allocated using malloc and
//    single block of object memory will be carved out of it.
// 4) If all of the above fail, the allocation fails an nullptr is returned.
//
// Typically, allocation operations are O(1), but occasionally will be
// O(SlabMalloc::Allocate) if a new slab needs to be allocated.  Free operations
// are always O(1).
//
// Slab size is determined by the SLAB_SIZE parameter of the
// SlabAllocatorTraits<> struct and  defaults to 16KB.  The maximum number of
// slabs the allocator is allow to create is determined at construction time.
// Additionally, an optional bool (default == false) may be passed to the
// constructor telling it to attempt to allocate at least one slab up front.
// Setting the slab limit to 1 and pre-allocating that slab during construction
// will ensure O(1) for all allocations.
//
// :: Thread Safety ::
//
// By default, SlabAllocators use a fbl::Mutex is used internally to ensure
// that allocation and free operations are thread safe.  The only external
// function called while holding the internal mutex is ::malloc.
//
// This behavior may be changed by changing the LockType template parameter of
// the SlabAllocatorTraits<> struct to be the name of the class which will
// implement the locking behavior.  The class chosen must be compatible with
// fbl::AutoLock.  fbl::NullLock may be used if no locking is what is wanted.
// UnlockedInstancedSlabAllocatorTraits or UnlockedStaticSlabAllocatorTraits may
// be used as a shorthand for this.
//
// ** Example **
//
// using MyAllocatorTraits =
//     fbl::SlabAllocatorTraits<fbl::unique_ptr<MyObject>,
//                               fbl::DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
//                               fbl::NullLock,
//                               true>;
// fbl::SlabAllocator<MyAllocatorTraits> allocator;
//
// or...
//
// fbl::SlabAllocator<UnlockedStaticSlabAllocator<fbl::unique_ptr<MyObject>> allocator;
//
// :: Object Requirements ::
//
// Objects must be small enough that at least 1 can be allocated from a slab
// after taking alignment and internal slab bookkeeping into account.  If the
// object is too large (unlikely) the slab size must be increased.  This
// requirement is enforced with a static_assert, so any problems here should be
// caught at compile time.  MyAllocatorType::AllocsPerSlab is a constexpr which
// reports the number of allocations the compiler was able to carve out of each
// slab.
//
// All objects must derive from SlabAllocated<T> where T are the same
// SlabAllocatorTraits<> used to create the SlabAllocator itself.
//
// Deriving from SlabAllocated<> automatically provides the custom deletion
// behavior which allows the pointer to automatically return to the proper
// allocator when delete is called on the pointer (in the case of unmanaged
// pointers) or when the pointer goes completely out of scope (in the case of
// managed pointers).
//
// In the case of instanced slab allocators, the SlabAllocated<> class also
// provides storage for the pointer which will be used for the allocation to
// find its way back to its originating allocator.
//
// In the case of static slab allocators, the SlabAllocated<> class introduces
// no storage overhead to the object, it just supplies the type information
// needed for the object to automatically return to its allocator.
//
// In addition to instanced and static, there is a manual-delete flavor of slab
// allocator as well.  Manual-delete allocators are instanced (and have
// independent quotas), but objects allocated from manual-delete slab allocators
// do not pay the cost of a pointer to find their way back to the allocator they
// came from.  Instead, it is the user's responsibility to return the object to
// the allocator by calling allocator.Delete(obj_ptr) at the end of its life.
// Users are responsible for tracking which objects came from which allocator.
//
// :: Static Allocator Storage ::
//
// Static slab allocators require that the storage required for the allocator to
// function be declared instantiated in a translation unit somewhere in the
// program.  In addition, if the allocator is going to be used outside of just
// this one translation unit, the existance of the storage must be forward
// declared to all of the users of the allocator.
//
// Given the precondition...
//
//   class MyObject;
//   using SATraits = fbl::StaticAllocatorTraits<fbl::unique_ptr<MyObject>>;
//
// The formal syntax for forward declaring the existance of the allocator
// storage would be...
//
//   template<>
//   typename fbl::SlabAllocator<SATraits>::InternalAllocatorType
//   fbl::SlabAllocator<SATraits>::allocator_;
//
// And the formal syntax for instantiating the allocator storage would be...
//
//   template<>
//   typename fbl::SlabAllocator<SATraits>::InternalAllocatorType
//   fbl::SlabAllocator<SATraits>::allocator_(ctor_args...);
//
// To ease some of this pain, a two helper macro is provided.  In the header
// file in your program defines the allocator, you can write...
//
//   FWD_DECL_STATIC_SLAB_ALLOCATOR(SATraits);
//
// Then, in a .cpp file somewhere in your program, you can write...
//
//   DECLARE_STATIC_SLAB_ALLOCATOR_STORAGE(SATraits, ctor_args...);
//
// :: API ::
//
// The slab allocator API consists of 2 methods.
// ++ Ctor(size_t, bool)
// ++ New(...)
//
// The allocator constructor takes two arguments.  The first is the maximum
// number of slabs the allocator is permitted to allocate.  The second is a bool
// which specifies whether or not an attempt should be made to pre-allocate the
// first slab.  By default, this defaults to false.  As noted earlier, limiting
// the total number of slabs to 1 and pre-allocating the slab during
// construction guarantees O(1) allocations during operation.
//
// New(...) is used to construct and return a pointer (of designated type) to an
// object allocated from slab memory.  An appropriate form of nullptr will be
// returned if the allocator has reached its allocation limit.  New(...) will
// accept any set of parameters compatible with one of an object's constructors.
//
// ***********************
// ** Unmanaged Example **
// ***********************
//
// class MyObject : public fbl::SinglyLinkedListable<MyObject*> {
// public:
//     explicit MyObject(int val) : my_int_(val) { }
//     explicit MyObject(const char* val) : my_string_(val) { }
// private:
//     int my_int_ = 0;
//     const char* my_string_ = nullptr;
// };
//
// /* Make an instanced slab allocator with 4KB slabs which dispenses
//  * unmanaged pointers and uses no locks */
// using AllocatorTraits = fbl::UnlockedSlabAllocatorTraits<MyObject*, 4096u>;
// using AllocatorType   = fbl::SlabAllocator<AllocatorTraits>;
// using ObjListType     = fbl::SinglyLinkedList<MyObject*>;
//
// void my_function() {
//     AllocatorType allocator(1, true);   /* one pre-allocated slab */
//     ObjListType list;
//
//     /* Allocate a slab's worth of objects and put them on a list.  Use both
//      * constructors. */
//     for (size_t i = 0; i < AllocatorType::AllocsPerSlab; ++i) {
//         auto ptr = FlipACoin()
//                  ? allocator.New(5)                     /* int form */
//                  : allocator.New("this is a string");   /* string form */
//         list.push_front(ptr);
//     }
//
//     /* Do something with all of our objects */
//     for (auto& obj_ref : list)
//         DoSomething(obj_ref);
//
//     /* Return all of the objects to the allocator */
//     while(!list.is_empty())
//         delete list.pop_front();
// }
//
// ********************
// ** RefPtr Example **
// ********************
//
// /* Make a static slab allocator with default (16KB) sized slabs which
//  * dispenses RefPtr<>s and uses default (fbl::Mutex) locking.  Give the
//  * allocator permission to allocate up to 64 slabs, but do not attempt to
//  * pre-allocate the first.
//  */
// class MyObject;
// using AllocatorTraits = fbl::StaticSlabAllocatorTraits<fbl::RefPtr<MyObject>>;
// using AllocatorType   = fbl::SlabAllocator<AllocatorTraits>;
// using ObjListType     = fbl::SinglyLinkedList<fbl::RefPtr<MyObject>>;
//
// DECLARE_STATIC_SLAB_ALLOCATOR_STORAGE(AllocatorTraits, 64);
//
// class MyObject : public fbl::SlabAllocated<AllocatorTraits>,
//                  public fbl::RefCounted<MyObject>,
//                  public fbl::SinglyLinkedListable<fbl::RefPtr<MyObject>> {
// public:
//     explicit MyObject(int val) : my_int_(val) { }
//     explicit MyObject(const char* val) : my_string_(val) { }
// private:
//     int my_int_ = 0;
//     const char* my_string_ = nullptr;
// };
//
// void my_function() {
//     ObjListType list;
//
//     /* Allocate two slabs' worth of objects and put them on a list.  Use both
//      * constructors. */
//     for (size_t i = 0; i < (2 * AllocatorType::AllocsPerSlab); ++i) {
//         auto ptr = FlipACoin()
//                  ? AllocatorType::New(5)                     /* int form */
//                  : AllocatorType::New("this is a string");   /* string form */
//         list.push_front(ptr);
//     }
//
//     /* Do something with all of our objects */
//     for (auto& obj_ref : list)
//         DoSomething(obj_ref);
//
//     /* Clear the list and automatically return all of our objects */
//     list.clear();
// }
//
namespace fbl {

enum class SlabAllocatorFlavor {
    INSTANCED,
    STATIC,
    MANUAL_DELETE,
};

// fwd decls
template <typename T,
          size_t SLAB_SIZE,
          typename LockType,
          SlabAllocatorFlavor AllocatorFlavor,
          bool ENABLE_OBJ_COUNT>
struct SlabAllocatorTraits;
template <typename SATraits, typename = void> class SlabAllocator;
template <typename SATraits, typename = void> class SlabAllocated;

constexpr size_t DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE = (16 << 10u);

namespace internal {

template <bool>
class SAObjCounter;

template <>
class SAObjCounter<false> {
public:
    void Inc(void*) {}
    void Dec() {}
    void ResetMaxObjCount() {}
    size_t obj_count() const { return 0; }
    size_t max_obj_count() const { return 0; }
};

template <>
class SAObjCounter<true> {
public:
    void Inc(void* allocated_ptr) {
        if (allocated_ptr == nullptr) {
          return;
        }
        ++obj_count_;
        max_obj_count_ = max(obj_count_, max_obj_count_);
    }
    void Dec() { --obj_count_; }
    void ResetMaxObjCount() { max_obj_count_ = obj_count_; }
    size_t obj_count() const { return obj_count_; }
    size_t max_obj_count() const { return max_obj_count_; }

private:
    size_t obj_count_ = 0;
    size_t max_obj_count_ = 0;
};

// internal fwd-decls
template <typename T> struct SlabAllocatorPtrTraits;
template <typename SATraits> class SlabAllocator;

// Support for raw pointers
template <typename T>
struct SlabAllocatorPtrTraits<T*> {
    using ObjType = T;
    using PtrType = T*;

    static constexpr bool IsManaged = false;
    static constexpr PtrType CreatePtr(ObjType* ptr) { return ptr; }
};

// Support for unique_ptr
template <typename T>
struct SlabAllocatorPtrTraits<unique_ptr<T>> {
    using ObjType = T;
    using PtrType = unique_ptr<T>;

    static constexpr bool IsManaged = true;
    static constexpr PtrType CreatePtr(ObjType* ptr) { return PtrType(ptr); }
};

// Support for RefPtr
template <typename T>
struct SlabAllocatorPtrTraits<RefPtr<T>> {
    using ObjType = T;
    using PtrType = RefPtr<T>;

    static constexpr bool IsManaged = true;
    static constexpr PtrType CreatePtr(ObjType* ptr) { return AdoptRef<ObjType>(ptr); }
};

// Trait class used to set the origin of a slab allocated object, if needed.
template <typename SATraits, typename = void>
struct SlabOriginSetter {
    static inline void SetOrigin(typename SATraits::ObjType* ptr,
                                 internal::SlabAllocator<SATraits>* origin) {
        ZX_DEBUG_ASSERT((ptr != nullptr) && (origin != nullptr));
        ptr->slab_origin_ = origin;
    }
};

// Slab allocated objects from STATIC and MANUAL_DELETE slab allocators do not
// have (or need) a slab_origin.  Their "origin setter" is a no-op.
template <typename SATraits>
struct SlabOriginSetter<SATraits,
                        typename std::enable_if<
                            (SATraits::AllocatorFlavor == SlabAllocatorFlavor::STATIC) ||
                            (SATraits::AllocatorFlavor == SlabAllocatorFlavor::MANUAL_DELETE)
                        >::type> {

    static inline void SetOrigin(typename SATraits::ObjType* ptr,
                                 internal::SlabAllocator<SATraits>* origin) { }
};

// Non-templated SlabAllocatorBase.  Any code which does not strictly depend on
// trait/type awareness lives here in order to minimize code size explosion due
// to template expansion.
class SlabAllocatorBase {
protected:
    struct FreeListEntry : public SinglyLinkedListable<FreeListEntry*> { };

    struct Slab {
        explicit Slab(size_t initial_bytes_used) : bytes_used_(initial_bytes_used) { }

        void* Allocate(size_t alloc_size, size_t slab_storage_limit) {
            if ((bytes_used_ + alloc_size) > slab_storage_limit)
                return nullptr;

            void* ret = storage_ + bytes_used_;
            bytes_used_ += alloc_size;
            return ret;
        }

        SinglyLinkedListNodeState<Slab*> sll_node_state_;
        size_t                           bytes_used_;
        uint8_t                          storage_[];
    };

    static constexpr size_t SlabOverhead = offsetof(Slab, storage_);

public:
    DISALLOW_COPY_ASSIGN_AND_MOVE(SlabAllocatorBase);

    SlabAllocatorBase(size_t slab_size,
                      size_t alloc_size,
                      size_t alloc_alignment,
                      size_t initial_slab_used,
                      size_t max_slabs,
                      bool   alloc_initial)
        : slab_size_(slab_size),
          slab_alignment_(max(alignof(Slab), alloc_alignment)),
          slab_storage_limit_(slab_size - SlabOverhead + initial_slab_used),
          alloc_size_(alloc_size),
          initial_slab_used_(initial_slab_used),
          max_slabs_(max_slabs) {
        // Attempt to ensure that at least one slab has been allocated before
        // finishing construction if the user has asked us to do so.  In some
        // situations, this can help to ensure that allocation performance is
        // always O(1), provided that the slab limit has been configured to be
        // 1.
        if (alloc_initial) {
            // No need to take the lock here, no one can possible know about us
            // yet.
            void* first_alloc = AllocateLocked();
            if (first_alloc != nullptr)
                ReturnToFreeListLocked(first_alloc);
        }
    }

    ~SlabAllocatorBase() {
#if ZX_DEBUG_ASSERT_IMPLEMENTED
        size_t allocated_count = 0;
        size_t free_list_size = this->free_list_.size_slow();
#endif
        // null out the free list so that it does not assert that we left
        // unmanaged pointers on it as we destruct, and so that the free list
        // does not attempt to auto-destruct the managed objects which were
        // present on it after the slab memory has been freed
        this->free_list_.clear_unsafe();

        while (!slab_list_.is_empty()) {
            Slab* free_me = slab_list_.pop_front();
#if ZX_DEBUG_ASSERT_IMPLEMENTED
            size_t bytes_used = free_me->bytes_used_ - initial_slab_used_;
            ZX_DEBUG_ASSERT(free_me->bytes_used_ >= initial_slab_used_);
            ZX_DEBUG_ASSERT((bytes_used % alloc_size_) == 0);
            allocated_count += (bytes_used / alloc_size_);
#endif
            SlabMalloc::Free(reinterpret_cast<void*>(free_me));
        }

        // Make sure that everything which was ever allocated had been returned
        // to the free list before we were destroyed.
        ZX_DEBUG_ASSERT_COND(free_list_size == allocated_count);
    }

    size_t max_slabs() const { return max_slabs_; }
    size_t slab_count() const { return slab_count_; }

protected:
    void* AllocateLocked() {
        // If we can alloc from the free list, do so.
        if (!free_list_.is_empty()) {
            return free_list_.pop_front();
        }

        // If we can allocate from the currently active slab, do so.
        if (!slab_list_.is_empty()) {
            auto& active_slab = slab_list_.front();
            void* mem = active_slab.Allocate(alloc_size_, slab_storage_limit_);
            if (mem)
                return mem;
        }

        // If we are allowed to allocate new slabs, try to do so.
        if (slab_count_ < max_slabs_) {
            void* slab_mem = SlabMalloc::Allocate(slab_size_, slab_alignment_);
            if (slab_mem != nullptr) {
                Slab* slab = new (slab_mem) Slab(initial_slab_used_);

                slab_count_++;
                slab_list_.push_front(slab);

                return slab->Allocate(alloc_size_, slab_storage_limit_);
            }
        }

        // Looks like we have run out of resources.
        return nullptr;
    }

    void ReturnToFreeListLocked(void* ptr) {
        FreeListEntry* free_obj = new (ptr) FreeListEntry;
        free_list_.push_front(free_obj);
    }

private:
    // Constant properties of the allocator passed to us by our templated
    // wrapper during construction.
    const size_t slab_size_;
    const size_t slab_alignment_;
    const size_t slab_storage_limit_;
    const size_t alloc_size_;
    const size_t initial_slab_used_;
    const size_t max_slabs_;

    SinglyLinkedList<FreeListEntry*> free_list_;
    SinglyLinkedList<Slab*>          slab_list_;
    size_t                           slab_count_ = 0;
};

template <typename SATraits>
class SlabAllocator : public SlabAllocatorBase {
public:
    using PtrTraits = typename SATraits::PtrTraits;
    using PtrType   = typename SATraits::PtrType;
    using ObjType   = typename SATraits::ObjType;

protected:
    static constexpr size_t SLAB_SIZE  = SATraits::SLAB_SIZE;
    static constexpr size_t AllocSize  = max(sizeof(FreeListEntry), sizeof(ObjType));
    static constexpr size_t AllocAlign = max(alignof(FreeListEntry), alignof(ObjType));

    static_assert(AllocAlign > 0, "Alignment requirements cannot be zero!");
    static_assert(!(AllocSize % AllocAlign),
                  "Allocation size must be a multiple of allocation alignment!");

    static constexpr size_t SlabStorageMisalignment = SlabAllocatorBase::SlabOverhead % AllocAlign;
    static constexpr size_t InitialSlabUse = SlabStorageMisalignment
                                           ? AllocAlign - SlabStorageMisalignment
                                           : 0;
    static constexpr size_t TotalSlabOverhead = SlabAllocatorBase::SlabOverhead + InitialSlabUse;

    static_assert((sizeof(Slab) < SATraits::SLAB_SIZE) || (TotalSlabOverhead < SATraits::SLAB_SIZE),
                  "SLAB_SIZE too small to hold slab bookkeeping");

public:
    static constexpr size_t AllocsPerSlab = (SLAB_SIZE - TotalSlabOverhead) / AllocSize;

    static_assert(AllocsPerSlab > 0, "SLAB_SIZE too small to hold even 1 allocation");

    // Slab allocated objects must derive from SlabAllocated<SATraits>.
    static_assert(is_base_of<SlabAllocated<SATraits>, ObjType>::value,
                  "Objects which are slab allocated from an allocator of type "
                  "SlabAllocator<T> must derive from SlabAllocated<T>.");

    DISALLOW_COPY_ASSIGN_AND_MOVE(SlabAllocator);

    explicit SlabAllocator(size_t max_slabs, bool alloc_initial = false)
        : SlabAllocatorBase(SLAB_SIZE,
                            AllocSize,
                            AllocAlign,
                            InitialSlabUse,
                            max_slabs,
                            alloc_initial) { }

    ~SlabAllocator() { }

    template <typename... ConstructorSignature>
    PtrType New(ConstructorSignature&&... args) {
        void* mem = Allocate();

        if (mem == nullptr)
            return nullptr;

        // Construct the object
        //
        // Note: This rather odd forwarding of this construction operation to
        // the non-internal form of the slab allocator is deliberate.  This
        // prevents object with private constructors from needing to be friends
        // of a fbl::internal class (a class which they should not need to know
        // about).
        ObjType* obj = ::fbl::SlabAllocator<SATraits>::ConstructObject(
                mem,
                std::forward<ConstructorSignature>(args)...);

        // Now, record the slab allocator this object came from so it can be
        // returned later on.
        //
        // Note: This is a no-op in the case of an object which came from a
        // static slab allocator (who's road home is determined purely by type)
        SlabOriginSetter<SATraits>::SetOrigin(obj, this);

        return PtrTraits::CreatePtr(obj);
    }

    size_t obj_count() const {
        static_assert(SATraits::ENABLE_OBJ_COUNT,
                      "Error accessing obj_count: Object counter not enabled in SATraits.");
        return sa_obj_counter_.obj_count();
    }
    size_t max_obj_count() const {
        static_assert(SATraits::ENABLE_OBJ_COUNT,
                      "Error accessing max_obj_count: Object counter not enabled in SATraits.");
        return sa_obj_counter_.max_obj_count();
    }
    void ResetMaxObjCount() {
        static_assert(SATraits::ENABLE_OBJ_COUNT,
                      "Error performing ResetMaxObjCount: Object counter not enabled in SATraits.");
        AutoLock alloc_lock(&alloc_lock_);
        sa_obj_counter_.ResetMaxObjCount();
    }

protected:
    friend class ::fbl::SlabAllocator<SATraits>;
    friend class ::fbl::SlabAllocated<SATraits>;

    void* Allocate() {
        AutoLock alloc_lock(&this->alloc_lock_);
        void* ptr = AllocateLocked();
        sa_obj_counter_.Inc(ptr);
        return ptr;
    }

    void ReturnToFreeList(void* ptr) {
        FreeListEntry* free_obj = new (ptr) FreeListEntry;
        {
            AutoLock alloc_lock(&alloc_lock_);
            ReturnToFreeListLocked(free_obj);
            sa_obj_counter_.Dec();
        }
    }

    typename SATraits::LockType alloc_lock_;
    SAObjCounter<SATraits::ENABLE_OBJ_COUNT> sa_obj_counter_;
};
}  // namespace internal

////////////////////////////////////////////////////////////////////////////////
//
// Fundamental traits which control the properties of a slab allocator.
//
// Parameters:
// ++ T
//  The pointer type of the object to be created by the allocator.  Must be one
//  of the following...
//  ++ ObjectType*
//  ++ fbl::unique_ptr<ObjectType>
//  ++ fbl::RefPtr<ObjectType>
//
// ++ SLAB_SIZE
//  The size (in bytes) of an individual slab.  Defaults to 16KB
//
// ++ LockType
//  The fbl::AutoLock compatible class which will handle synchronization.
//
// ++ AllocatorType
//  Selects between a the three flavors of allocator.
//  ++ INSTANCED - Allocations come from an instance of an allocator.
//     Allocation objects carry the overhead of an "origin pointer" which will
//     be used to find their way home when the delete operator is applied to the
//     object.  Each instance of an allocator has it's own slab quota.
//  ++ STATIC - Allocations come from a static instance of an allocator.  There
//     is only one allocation pool for the entire process.  All allocator
//     methods are static members of the allocator's type and use the
//     MyAllocator::Method syntax (instead of my_allocator.Method).  Allocation
//     objects carry no overhead and will find their way home based on type when
//     the delete operator is applied to them.
//  ++ MANUAL_DELETE - A type of INSTANCED allocator where objects have no
//     pointer overhead.  The delete operator of the object is hidden in the
//     SlabAllocated<> class preventing users from delete'ing these objects.
//     Users must be aware of where their allocations came from and are
//     responsible for calling allocator.Delete in order to destruct and return
//     the object to the allocator it came from.  MANUAL_DELETE allocators are
//     only permitted for unmanaged pointer types.
//
////////////////////////////////////////////////////////////////////////////////
template <typename T,
          size_t   _SLAB_SIZE = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
          typename _LockType  = ::fbl::Mutex,
          SlabAllocatorFlavor _AllocatorFlavor = SlabAllocatorFlavor::INSTANCED,
          bool _ENABLE_OBJ_COUNT = false>
struct SlabAllocatorTraits {
    using PtrTraits     = internal::SlabAllocatorPtrTraits<T>;
    using PtrType       = typename PtrTraits::PtrType;
    using ObjType       = typename PtrTraits::ObjType;
    using LockType      = _LockType;

    static constexpr size_t SLAB_SIZE = _SLAB_SIZE;
    static constexpr SlabAllocatorFlavor AllocatorFlavor = _AllocatorFlavor;
    static constexpr bool ENABLE_OBJ_COUNT = _ENABLE_OBJ_COUNT;
};

////////////////////////////////////////////////////////////////////////////////
//
// Implementation of an instanced slab allocator.
//
////////////////////////////////////////////////////////////////////////////////
template <typename SATraits>
class SlabAllocator<SATraits,
                    typename std::enable_if<
                        (SATraits::AllocatorFlavor == SlabAllocatorFlavor::INSTANCED) ||
                        (SATraits::AllocatorFlavor == SlabAllocatorFlavor::MANUAL_DELETE)
                    >::type>
      : public internal::SlabAllocator<SATraits> {
public:
    using PtrTraits         = typename SATraits::PtrTraits;
    using PtrType           = typename SATraits::PtrType;
    using ObjType           = typename SATraits::ObjType;
    using BaseAllocatorType = internal::SlabAllocator<SATraits>;

    static constexpr size_t AllocsPerSlab = BaseAllocatorType::AllocsPerSlab;

    explicit SlabAllocator(size_t max_slabs, bool alloc_initial = false)
        : BaseAllocatorType(max_slabs, alloc_initial) { }

    ~SlabAllocator() { }

    void Delete(ObjType* ptr) {
        static_assert(SATraits::AllocatorFlavor == SlabAllocatorFlavor::MANUAL_DELETE,
                      "Only MANUAL_DELETE slab allocators have a Delete method!");
        ptr->~ObjType();
        BaseAllocatorType::ReturnToFreeList(ptr);
    }

private:
    friend class internal::SlabAllocator<SATraits>; // internal::SA<> gets to call ConstructObject

    template <typename... ConstructorSignature>
    static ObjType* ConstructObject(void* mem, ConstructorSignature&&... args) {
        return new (mem) ObjType(std::forward<ConstructorSignature>(args)...);
    }
};

template <typename SATraits>
class SlabAllocated<SATraits,
                    typename std::enable_if<
                        (SATraits::AllocatorFlavor == SlabAllocatorFlavor::INSTANCED)
                    >::type> {
public:
    using AllocatorType = internal::SlabAllocator<SATraits>;
    using ObjType       = typename SATraits::ObjType;

     SlabAllocated() { }
    ~SlabAllocated() { }

    DISALLOW_COPY_ASSIGN_AND_MOVE(SlabAllocated);

    void operator delete(void* ptr) {
        // Note: this is a bit sketchy...  We have been destructed at this point
        // in time, but we are about to access our slab_origin_ member variable.
        // The *only* reason that this is OK is that we know that our destructor
        // does not touch slab_origin_, and no one else in our hierarchy should
        // be able to modify slab_origin_ because it is private.
        ObjType* obj_ptr = reinterpret_cast<ObjType*>(ptr);

        ZX_DEBUG_ASSERT(obj_ptr != nullptr);
        ZX_DEBUG_ASSERT(obj_ptr->slab_origin_ != nullptr);
        obj_ptr->slab_origin_->ReturnToFreeList(obj_ptr);
    }

private:
    friend struct internal::SlabOriginSetter<SATraits>;
    AllocatorType* slab_origin_ = nullptr;
};

template <typename SATraits>
class SlabAllocated<SATraits,
                    typename std::enable_if<
                        (SATraits::PtrTraits::IsManaged == false) &&
                        (SATraits::AllocatorFlavor == SlabAllocatorFlavor::MANUAL_DELETE)
                    >::type> {
public:
     SlabAllocated() { }
    ~SlabAllocated() { }

    DISALLOW_COPY_ASSIGN_AND_MOVE(SlabAllocated);

protected:
    // Object which come from a MANUAL_DELETE slab allocator may not be
    // destroyed using the delete operator.  Instead, users must return the
    // object to its allocator using the Delete method of the allocator
    // instance.
    //
    // Hide the delete operator, and halt-and-catch-fire if some Bad Person ever
    // manages to generate a call to this operator.
    //
    // Note: it would be nice to either = delete this operator, or at least make
    // it private, but we cannot.  To do so would prevent the implemementer of
    // the slab allocated object from defining a destructor.
    void operator delete(void*) { ZX_DEBUG_ASSERT(false); }
};

// Shorthand for declaring the properties of an instanced allocator (somewhat
// superfluous as the default is instanced)
template <typename T,
          size_t   SLAB_SIZE = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
          typename LockType  = ::fbl::Mutex,
          bool     ENABLE_OBJ_COUNT = false>
using InstancedSlabAllocatorTraits =
    SlabAllocatorTraits<T, SLAB_SIZE, LockType, SlabAllocatorFlavor::INSTANCED, ENABLE_OBJ_COUNT>;

template <typename T,
          size_t   SLAB_SIZE = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
          bool     ENABLE_OBJ_COUNT = false>
using UnlockedInstancedSlabAllocatorTraits =
    SlabAllocatorTraits<T, SLAB_SIZE, ::fbl::NullLock, SlabAllocatorFlavor::INSTANCED,
                        ENABLE_OBJ_COUNT>;

template <typename T,
          size_t   SLAB_SIZE = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
          bool     ENABLE_OBJ_COUNT = false>
using UnlockedSlabAllocatorTraits =
    SlabAllocatorTraits<T, SLAB_SIZE, ::fbl::NullLock, SlabAllocatorFlavor::INSTANCED,
                        ENABLE_OBJ_COUNT>;

// Shorthand for declaring the properties of a MANUAL_DELETE slab allocator.
template <typename T,
          size_t   SLAB_SIZE = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
          typename LockType  = ::fbl::Mutex,
          bool     ENABLE_OBJ_COUNT = false>
using ManualDeleteSlabAllocatorTraits =
    SlabAllocatorTraits<T, SLAB_SIZE, LockType, SlabAllocatorFlavor::MANUAL_DELETE,
                        ENABLE_OBJ_COUNT>;

template <typename T,
          size_t   SLAB_SIZE = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
          bool     ENABLE_OBJ_COUNT = false>
using UnlockedManualDeleteSlabAllocatorTraits =
    SlabAllocatorTraits<T, SLAB_SIZE, ::fbl::NullLock, SlabAllocatorFlavor::MANUAL_DELETE,
                        ENABLE_OBJ_COUNT>;

////////////////////////////////////////////////////////////////////////////////
//
// Implementation of a static slab allocator.
//
////////////////////////////////////////////////////////////////////////////////
template <typename SATraits>
class SlabAllocator<SATraits,
                    typename std::enable_if<
                        (SATraits::AllocatorFlavor == SlabAllocatorFlavor::STATIC)
                    >::type> {
public:
    using PtrTraits             = typename SATraits::PtrTraits;
    using PtrType               = typename SATraits::PtrType;
    using ObjType               = typename SATraits::ObjType;
    using InternalAllocatorType = internal::SlabAllocator<SATraits>;

    static constexpr size_t AllocsPerSlab = InternalAllocatorType::AllocsPerSlab;

    // Do not allow instantiation of static slab allocators.
    SlabAllocator() = delete;

    template <typename... ConstructorSignature>
    static PtrType New(ConstructorSignature&&... args) {
        return allocator_.New(std::forward<ConstructorSignature>(args)...);
    }

    static size_t max_slabs() { return allocator_.max_slabs(); }
    static size_t obj_count() { return allocator_.obj_count(); }
    static size_t max_obj_count() { return allocator_.max_obj_count(); }
    static size_t slab_count() { return allocator_.slab_count(); }
    static void ResetMaxObjCount() { allocator_.ResetMaxObjCount(); }

private:
    friend class SlabAllocated<SATraits>;           // SlabAllocated<> gets to call ReturnToFreeList
    friend class internal::SlabAllocator<SATraits>; // internal::SA<> gets to call ConstructObject

    template <typename... ConstructorSignature>
    static ObjType* ConstructObject(void* mem, ConstructorSignature&&... args) {
        return new (mem) ObjType(std::forward<ConstructorSignature>(args)...);
    }

    static void ReturnToFreeList(void* ptr) { allocator_.ReturnToFreeList(ptr); }
    static InternalAllocatorType allocator_;
};

template <typename SATraits>
class SlabAllocated<SATraits,
                    typename std::enable_if<
                        (SATraits::AllocatorFlavor == SlabAllocatorFlavor::STATIC)
                    >::type> {
public:
    SlabAllocated() { }
    DISALLOW_COPY_ASSIGN_AND_MOVE(SlabAllocated);

    using AllocatorType = SlabAllocator<SATraits>;
    using ObjType       = typename SATraits::ObjType;

    void operator delete(void* ptr) {
        ZX_DEBUG_ASSERT(ptr != nullptr);
        AllocatorType::ReturnToFreeList(reinterpret_cast<ObjType*>(ptr));
    }
};

// Shorthand for declaring the properties of a static allocator
template <typename T,
          size_t   SLAB_SIZE = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
          typename LockType  = ::fbl::Mutex,
          bool     ENABLE_OBJ_COUNT = false>
using StaticSlabAllocatorTraits =
    SlabAllocatorTraits<T, SLAB_SIZE, LockType, SlabAllocatorFlavor::STATIC, ENABLE_OBJ_COUNT>;

template <typename T,
          size_t   SLAB_SIZE = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
          bool     ENABLE_OBJ_COUNT = false>
using UnlockedStaticSlabAllocatorTraits =
    SlabAllocatorTraits<T, SLAB_SIZE, ::fbl::NullLock, SlabAllocatorFlavor::STATIC,
                        ENABLE_OBJ_COUNT>;

// Shorthand for declaring the global storage required for a static allocator
#define DECLARE_STATIC_SLAB_ALLOCATOR_STORAGE(ALLOC_TRAITS, ...) \
template<> ::fbl::SlabAllocator<ALLOC_TRAITS>::InternalAllocatorType \
fbl::SlabAllocator<ALLOC_TRAITS>::allocator_(__VA_ARGS__)

// Shorthand for forward declaring the existance of the storage required to use
// a static slab allocator.  Use this macro in your header file if your static
// slab allocator is to be used outside of a single translational unit.
#define FWD_DECL_STATIC_SLAB_ALLOCATOR(ALLOC_TRAITS) \
template<> ::fbl::SlabAllocator<ALLOC_TRAITS>::InternalAllocatorType \
fbl::SlabAllocator<ALLOC_TRAITS>::allocator_;


}  // namespace fbl
