PageRenderTime 8ms CodeModel.GetById 4ms app.highlight 3ms RepoModel.GetById 0ms app.codeStats 0ms

/sparrowhawk/foundation/ESFFixedAllocator.h

http://github.com/jtblatt/duderino
C Header | 188 lines | 43 code | 23 blank | 122 comment | 0 complexity | df66579033d216ab254421f2e59dbf06 MD5 | raw file
  1/** @file ESFFixedAllocator.h
  2 *  @brief A ESFAllocator implementation good for fixed-length allocations.
  3 *
  4 * Copyright (c) 2009 Yahoo! Inc.
  5 * The copyrights embodied in the content of this file are licensed by Yahoo! Inc.
  6 * under the BSD (revised) open source license.
  7 *
  8 * Derived from code that is Copyright (c) 2009 Joshua Blatt and offered under both
  9 * BSD and Apache 2.0 licenses (http://sourceforge.net/projects/sparrowhawk/).
 10 *
 11 *    $Author: blattj $
 12 *    $Date: 2009/05/25 21:51:08 $
 13 *    $Name:  $
 14 *    $Revision: 1.3 $
 15 */
 16
 17#ifndef ESF_FIXED_ALLOCATOR_H
 18#define ESF_FIXED_ALLOCATOR_H
 19
 20#ifndef ESF_CONFIG_H
 21#include <ESFConfig.h>
 22#endif
 23
 24#ifndef ESF_ALLOCATOR_H
 25#include <ESFAllocator.h>
 26#endif
 27
 28#ifndef ESF_TYPES_H
 29#include <ESFTypes.h>
 30#endif
 31
 32/** ESFFixedAllocator realizes the ESFAllocator interface with a simple fixed
 33 *  length allocator.  The ESFFixedAllocator handles memory reservation and
 34 *  compaction very efficiently with the low overhead of 1 word per
 35 *  allocation because of its limitation that all allocations are always the
 36 *  same, fixed size.
 37 *
 38 *  @ingroup allocator
 39 */
 40class ESFFixedAllocator: public ESFAllocator {
 41public:
 42
 43    /** Constructor.  Creates the ESFFixedAllocator given the number of blocks
 44     *  and size of each block for its memory pool and also a source allocator
 45     *  from which it will request its memory pool.  The amount of memory it
 46     *  will actually request from the source allocator is blocks * blockSize
 47     *  plus one word per block.
 48     *
 49     *  @param blocks The number of blocks this allocator can allocate before
 50     *      exhausting its memory pool.
 51     *  @param blockSize The size in bytes of each block.
 52     *  @param source The allocator to use to allocate the memory pool.
 53     */
 54    ESFFixedAllocator(int blocks, int blockSize, ESFAllocator *source);
 55
 56    /** Destructor.  If initialized, the allocator will call the its destroy
 57     *  method.  The destroy method may or may not return the allocator's
 58     *  managed memory to its source allocator.
 59     */
 60    virtual ~ESFFixedAllocator();
 61
 62    /** Allocate a word-aligned memory block of at least size bytes.
 63     *
 64     *  @param size The minimum number of bytes to allocate.
 65     *  @return a word-aligned memory block of at least size bytes if
 66     *      successful, NULL otherwise.
 67     */
 68    virtual void *allocate(ESFUWord size);
 69
 70    /** Deallocate a memory block allocated by this allocator or by its
 71     *  failover allocators.
 72     *
 73     *  @param block The block to deallocate
 74     *  @return ESF_SUCCESS if the block was successfully deallocated, another
 75     *      error code otherwise.  ESF_NOT_OWNER will be returned if the
 76     *      block was not allocated by this allocator.
 77     */
 78    virtual ESFError deallocate(void *block);
 79
 80    /** Get the overhead in bytes of any additional control structures
 81     *  attached to an allocated block.  This can be used to optimize
 82     *  allocation requests for some allocators.  Power of two allocators,
 83     *  for example, will always round the size requested + the overhead up
 84     *  to the next power of two.  If the caller always requests powers of
 85     *  two, then the allocator can waste a lot of memory.  If, however, the
 86     *  caller requests a power of two minus the allocator overhead, then
 87     *  the allocator will return the optimal amount of memory.
 88     *
 89     *  @return the allocator's overhead in bytes for each allocation.
 90     */
 91    virtual ESFUWord getOverhead();
 92
 93    /** Initialize this memory pool.
 94     *
 95     *  @return ESF_SUCCESS if successful, another error code otherwise.
 96     */
 97    virtual ESFError initialize();
 98
 99    /** Destroy this allocator.  The allocator will return all of the memory
100     *  it manages to its source allocator and return itself to a state where
101     *  initialize could be called again.  All memory should be returned to
102     *  the allocator before calling its destroy method.   Some implementations
103     *  may refuse to shutdown if they have outstanding allocations.
104     *
105     *  @return ESF_SUCCESS if the allocator could destroy itself, another
106     *      error code otherwise.  ESF_IN_USE will be returned if the
107     *      allocator has handed out memory that has not been returned.
108     *  @see initialize.
109     */
110    virtual ESFError destroy();
111
112    /** Get the allocator's current initialization state.
113     *
114     *  @return ESF_SUCCESS if the allocator is initialized,
115     *      ESF_NOT_INITIALIZED if the allocator has not been initialized,
116     *      another error code if an error occurred determining the
117     *      allocator's current state.
118     *  @see initialize.
119     */
120    virtual ESFError isInitialized();
121
122    /** Set another allocator to be used if this allocator cannot fulfill a
123     *  allocate request.  This failover allocator will be initialized lazily.
124     *  If a failover allocator is not set, an allocator will simply return
125     *  NULL if it cannot fulfill an allocation request.  Destroying an
126     *  allocator with registered failover allocators must also destroy those
127     *  failover allocators if they have been initialized.  Failover allocators
128     *  may be chained.  An allocator is responsible for determining whether
129     *  a block of memory to be deallocated came from itself or from its
130     *  failover allocator and take the appropriate action.  Allocators should
131     *  never be used as failover allocators for themselves to avoid
132     *  infinite recursion.
133     *
134     *  @param allocator The failover allocator.  Set to NULL to clear an
135     *      already registered failover allocator.
136     *  @return ESF_SUCCESS if successful, another error code otherwise.
137     */
138    virtual ESFError setFailoverAllocator(ESFAllocator *allocator);
139
140    /** Get the failover allocator used by this allocator.
141     *
142     *  @param allocator The failover allocator to get (pointer to a pointer).
143     *      This pointer will be set to NULL if no failover allocator exists.
144     *  @return ESF_SUCCESS if successful, another error code otherwise.  Note
145     *      that if no failover allocator exists, ESF_SUCCESS will be returned
146     *      and the allocator argument will be set to NULL.
147     *  @see setFailoverAllocator
148     */
149    virtual ESFError getFailoverAllocator(ESFAllocator **allocator);
150
151    /** Get the size of the blocks allocated by this allocator.
152     *
153     *  @return The block size of this allocator.
154     */
155    int getBlockSize();
156
157    /** Placement new.
158     *
159     *  @param size The size of the object.
160     *  @param allocator The source of the object's memory.
161     *  @return The new object or NULL of the memory allocation failed.
162     */
163    inline void *operator new(size_t size, ESFAllocator *allocator) {
164        return allocator->allocate(size);
165    }
166
167private:
168
169    //  Disabled
170    ESFFixedAllocator(const ESFFixedAllocator &);
171    ESFFixedAllocator &operator=(const ESFFixedAllocator &);
172
173    typedef struct AvailListElem {
174        AvailListElem *_next;
175    } AvailListElem;
176
177    AvailListElem *popAvailList();
178    void pushAvailList(AvailListElem *elem);
179
180    AvailListElem *_availList;
181    void *_pool;
182    ESFAllocator *_sourceAllocator;
183    ESFAllocator *_failoverAllocator;
184    ESFUWord _blockSize;
185    int _blocks;
186};
187
188#endif /* ! ESF_FIXED_ALLOCATOR_H */