/**
\page allocator Allocators

\tableofcontents
@section allocator Allocators

Allocators are used by dynamic data structures whose size is either known at
runtime or changes during execution, e.g., std::vector, std::set, etc. 
The default allocators in C/C++ often use a single lock on their internal heap,
and, therefore, do not scale with multiple threads. Similarly, \b malloc and \b
free, do not scale with multiple threads. As a result, parallel code that uses the
default C/C++ allocators does not scale beyond a few threads. In Galois, we have designed scalable
parallel allocators for some of the common usage patterns. We describe some of them
below:

\subsection per-iter-alloc Per Iteration Allocator
Per Iteration Allocator {@link galois::PerIterAllocTy} can be used when dynamic data structures are defined inside
the parallel loop and live for only one iteration of the loop. This allocator can
be used inside the functors for galois::for_each and galois::do_all. It can be used
with STL data structures, e.g., std::vector and std::set etc., and, supports
variable size allocations. 

We will use Delaunay Mesh Refinement (DMR), as an example to illustrate the use of the Per Iteration
Allocator. The following steps are required to access the Per Iteration Allocator:

\b TODO: add ref to functor flags
- The loop operator (functor) needs specify the \t tt_needs_per_iter_alloc
  flag, as a \b typedef, to enable the allocator. E.g., in DMR 
  {@link apps/delaunayrefinement/DelaunayRefinement.cpp}: 
  @snippet apps/delaunayrefinement/DelaunayRefinement.cpp Enabling Per Iteration Allocator in DMR

- A reference to the allocator can be accessed through 
  {@link galois::UserContext::getPerIterAlloc}, which can then be passed to dynamic
  data structures such as std::vector. E.g., in DMR
  {@link apps/delaunayrefinement/DelaunayRefinement.cpp}:
  @snippet apps/delaunayrefinement/DelaunayRefinement.cpp  Accessing Per Iteration Allocator in DMR

The following snippet shows how to define an STL vector to use the Per Iteration
Allocator (file {@link apps/delaunayrefinement/Cavity.h}):
@snippet apps/delaunayrefinement/Cavity.h STL vector using PerIterAllocTy

  
\subsection fixed-size-alloc Fixed Size Allocator

A common usage pattern is to allocate objects of the same type inside the parallel
loop. Such an allocator can be implemented easily in a scalable manner. Galois
provides {@link galois::GFixedAllocator}, which takes a template parameter as the
type of object to be allocated. It only supports allocating objects of one specific type
(and size), therefore, it cannot be used with STL data structures like std::vector
and std::deque, which allocate variable size chunks. However, it can be used with
STL data structures like std::set, and std::list, etc., which allocated objects of
one type only. The source for {@link galois::ThreadSafeOrderedSet} shows how
a fixed size allocator can be passed to std::set.

This allocator is typically instantiated outside the parallel loop by the master
thread and then can be used by multiple parallel loops.  An example from {@link
include/galois/gdeque.h} is shown below:

@snippet include/galois/gdeque.h Example Fixed Size Allocator


\subsection plugin-other-alloc Plugging in 3rd Party Allocators

{@link galois::runtime::MM::ExternRefGaloisAllocator} is a wrapper class that can
be used to wrap any third-party heap implementation, and make it use-able by Galois
and STL data structures. It takes the type-name of the heap implementation as a
template parameter and a reference to it for instantiating the allocator object.  

Following is an example of how \b malloc and \b free, from C, can be wrapped into
an allocator using this class, (see file {@link include/galois/runtime/mm/Mem.h}):
@snippet include/galois/runtime/mm/Mem.h Example Third Party Allocator


\b TODO: show snippet using MallocHeap

\subsection build-custom-alloc Types of Heaps and Building Custom Allocators

The allocators in Galois are implemented in a modular fashion. An allocator can
take a heap implementation as its template argument. A heap implementation defines 
two functions `void* allocate(size_t)` and `void deallocate(void*, size_t)`.
Several heap implementations are just wrappers around another heap implementation
to modify its interface in some way. In the following we list a few of them and
show an example:

- {@link galois::runtime::MM::SystemBaseAlloc} defines the basic heap
  implementation used by Galois allocators, and is the source of all heap memory.
  It is implemented as a list of pages stored by each thread. 

- {@link galois::runtime::MM::FreeListHeap} maintains a linked list of blocks of
  size *B*, where *B* is the size of the objects being allocated. This is a fixed
  size heap, and is a wrapper around a source heap implementation that is passed
  as a template argument.

- {@link galois::runtime::MM::SimpleBumpPtr} allows allocating different size
  objects within a block of memory by simply moving a pointer within the block. The
  size of the block is determined by the source heap implementation provided as a
  template argument. The memory within a block cannot be freed, however, blocks are 
  freed only at the end of the program when the SimpleBumpPtr's destructor is
  called.

- {@link galois::runtime::MM::ThreadAwarePrivateHeap} creates a per-thread instance
  of a source heap provided as a template argument. This is used for defining some
  of the parallel allocators. 

We show the Per Iteration Allocator, from {@link include/galois/Mem.h}, to show how
heap implementations can be combined together to form useful allocators:
@snippet include/galois/Mem.h PerIterAllocTy example

Another example, from {@link include/galois/runtime/mm/Mem.h} shows how  the Fixed
Size allocator is defined:
@snippet include/galois/runtime/mm/Mem.h FixedSizeAllocator example

*/
