/sparrowhawk/foundation/ESFSharedAllocator.h
C Header | 161 lines | 33 code | 19 blank | 109 comment | 0 complexity | 0391a4ebc5f89e523813c04b18c7e3c1 MD5 | raw file
1/** @file ESFSharedAllocator.h 2 * @brief A ESFAllocator decorator that can synchronize access to any allocator 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_SHARED_ALLOCATOR_H 18#define ESF_SHARED_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_MUTEX_H 29#include <ESFMutex.h> 30#endif 31 32/** ESFSharedAllocator is a decorator that can synchronize access 33 * to any other allocator with a mutex. 34 * 35 * @ingroup allocator 36 */ 37class ESFSharedAllocator: public ESFAllocator { 38public: 39 /** Constructor. 40 * 41 * @param allocator The decorated allocator to synchronize. 42 */ 43 ESFSharedAllocator(ESFAllocator *allocator); 44 45 /** Destructor. If initialized, the allocator will call the its destroy 46 * method. The destroy method may or may not return the allocator's 47 * managed memory to its source allocator. 48 */ 49 virtual ~ESFSharedAllocator(); 50 51 /** Allocate a word-aligned memory block of at least size bytes. 52 * 53 * @param size The minimum number of bytes to allocate. 54 * @return a word-aligned memory block of at least size bytes if 55 * successful, NULL otherwise. 56 */ 57 virtual void *allocate(ESFUWord size); 58 59 /** Deallocate a memory block allocated by this allocator or by its 60 * failover allocators. 61 * 62 * @param block The block to deallocate (pointer to a pointer). If 63 * freed, the block pointer will be set to NULL. 64 * @return ESF_SUCCESS if the block was successfully deallocated, another 65 * error code otherwise. ESF_NOT_OWNER will be returned if the 66 * block was not allocated by this allocator. 67 */ 68 virtual ESFError deallocate(void *block); 69 70 /** Get the overhead in bytes of any additional control structures 71 * attached to an allocated block. This can be used to optimize 72 * allocation requests for some allocators. Power of two allocators, 73 * for example, will always round the size requested + the overhead up 74 * to the next power of two. If the caller always requests powers of 75 * two, then the allocator can waste a lot of memory. If, however, the 76 * caller requests a power of two minus the allocator overhead, then 77 * the allocator will return the optimal amount of memory. 78 * 79 * @return the allocator's overhead in bytes for each allocation. 80 */ 81 virtual ESFUWord getOverhead(); 82 83 /** Initialize this memory pool. 84 * 85 * @return ESF_SUCCESS if successful, another error code otherwise. 86 */ 87 virtual ESFError initialize(); 88 89 /** Destroy this allocator. The allocator will return all of the memory 90 * it manages to its source allocator and return itself to a state where 91 * initialize could be called again. All memory should be returned to 92 * the allocator before calling its destroy method. Some implementations 93 * may refuse to shutdown if they have outstanding allocations. 94 * 95 * @return ESF_SUCCESS if the allocator could destroy itself, another 96 * error code otherwise. ESF_IN_USE will be returned if the 97 * allocator has handed out memory that has not been returned. 98 * @see initialize. 99 */ 100 virtual ESFError destroy(); 101 102 /** Get the allocator's current initialization state. 103 * 104 * @return ESF_SUCCESS if the allocator is initialized, 105 * ESF_NOT_INITIALIZED if the allocator has not been initialized, 106 * another error code if an error occurred determining the 107 * allocator's current state. 108 * @see initialize. 109 */ 110 virtual ESFError isInitialized(); 111 112 /** Set another allocator to be used if this allocator cannot fulfill a 113 * allocate request. This failover allocator will be initialized lazily. 114 * If a failover allocator is not set, an allocator will simply return 115 * NULL if it cannot fulfill an allocation request. Destroying an 116 * allocator with registered failover allocators must also destroy those 117 * failover allocators if they have been initialized. Failover allocators 118 * may be chained. An allocator is responsible for determining whether 119 * a block of memory to be deallocated came from itself or from its 120 * failover allocator and take the appropriate action. Allocators should 121 * never be used as failover allocators for themselves to avoid 122 * infinite recursion. 123 * 124 * @param allocator The failover allocator. Set to NULL to clear an 125 * already registered failover allocator. 126 * @return ESF_SUCCESS if successful, another error code otherwise. 127 */ 128 virtual ESFError setFailoverAllocator(ESFAllocator *allocator); 129 130 /** Get the failover allocator used by this allocator. 131 * 132 * @param allocator The failover allocator to get (pointer to a pointer). 133 * This pointer will be set to NULL if no failover allocator exists. 134 * @return ESF_SUCCESS if successful, another error code otherwise. Note 135 * that if no failover allocator exists, ESF_SUCCESS will be returned 136 * and the allocator argument will be set to NULL. 137 * @see setFailoverAllocator 138 */ 139 virtual ESFError getFailoverAllocator(ESFAllocator **allocator); 140 141 /** Placement new. 142 * 143 * @param size The size of the object. 144 * @param allocator The source of the object's memory. 145 * @return The new object or NULL of the memory allocation failed. 146 */ 147 inline void *operator new(size_t size, ESFAllocator *allocator) { 148 return allocator->allocate(size); 149 } 150 151private: 152 153 // Disabled 154 ESFSharedAllocator(const ESFSharedAllocator &); 155 ESFSharedAllocator &operator=(const ESFSharedAllocator &); 156 157 ESFAllocator *_allocator; 158 ESFMutex _mutex; 159}; 160 161#endif /* ! ESF_SHARED_ALLOCATOR_H */