Phoenix
Object-oriented orthogonally persistent operating system
|
00001 /* 00002 * /phoenix/include/common/BuddyAllocator.h 00003 * 00004 * This file is a part of Phoenix operating system. 00005 * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com> 00006 * All rights reserved. 00007 * See COPYING file for copyright details. 00008 */ 00009 00014 #ifndef BUDDYALLOCATOR_H_ 00015 #define BUDDYALLOCATOR_H_ 00016 00043 class BuddyAllocatorBase { 00044 public: 00048 typedef uintptr_t Addr; 00049 00051 enum :size_t { 00053 MAX_ORDER = sizeof(Addr) * NBBY, 00055 MAX_CACHE_SIZE = U16_MAX, 00056 }; 00057 00061 BuddyAllocatorBase(); 00062 00063 ~BuddyAllocatorBase(); 00064 00080 RetCode Initialize(Addr startAddress, Addr endAddress, int minOrder = 0, 00081 int maxOrder = -1, size_t cacheSize = 8192); 00082 00083 private: 00084 bool _isInitialized = false; 00085 Addr _startAddress, _endAddress; 00086 int _minOrder, _maxOrder; 00087 00089 class CacheEntry { 00090 public: 00091 typedef u16 Index; 00092 typedef Index ListHead; 00095 static const Index NONE = ~0; 00096 00097 int Compare(CacheEntry &e) { return address - e.address; } 00098 int Compare(Addr &address) { return address - this->address; } 00099 typedef RBTree<CacheEntry, &CacheEntry::Compare, Addr, &CacheEntry::Compare> Tree; 00100 00101 Addr address; 00102 Index next = NONE, 00103 prev = NONE; 00104 Tree::Entry treeEntry; 00105 00107 inline CacheEntry *GetPtr(CacheEntry *cache, Index idx) { return &cache[idx]; } 00109 inline Index GetIdx(CacheEntry *cache) { return this - cache; } 00110 00115 void Insert(CacheEntry *cache, ListHead &head); 00116 00121 void Delete(CacheEntry *cache, ListHead &head); 00122 }; 00123 00125 CacheEntry *_cache = 0; 00127 size_t _cacheSize; 00129 CacheEntry::ListHead _freeCacheEntries = CacheEntry::NONE; 00131 CacheEntry::Tree _cacheTree; 00132 00134 class OrderPool { 00135 public: 00141 RetCode Initialize(size_t numBlocks); 00142 ~OrderPool() {/* XXX */} 00143 private: 00144 u8 *_bitmapData = 0; 00145 BitString<> _bitmap; 00146 CacheEntry::ListHead _freeBlocks; 00147 }; 00148 00150 OrderPool *_pool = 0; 00151 00153 inline int _GetOrder(Addr size) { 00154 int order = 0; 00155 Addr osize = 1; 00156 while (osize < size) { 00157 order++; 00158 osize <<= 1; 00159 } 00160 return order; 00161 } 00162 00164 inline Addr _GetOrderSize(int order) { 00165 ASSERT(order >= 0); 00166 return 1 << order; 00167 } 00168 00170 void _Free(); 00171 }; 00172 00176 template <class AddrType> 00177 class BuddyAllocator : public BuddyAllocatorBase { 00178 public: 00179 inline BuddyAllocator() : BuddyAllocatorBase() { } 00180 00182 inline RetCode Initialize(AddrType startAddress, AddrType endAddress, 00183 int minOrder = 0, int maxOrder = -1, 00184 size_t cacheSize = 8192) 00185 { 00186 return BuddyAllocatorBase::Initialize(startAddress, endAddress, 00187 minOrder, maxOrder, cacheSize); 00188 } 00189 }; 00190 00191 00192 #endif /* BUDDYALLOCATOR_H_ */