Phoenix
Object-oriented orthogonally persistent operating system
BuddyAllocator.h
Go to the documentation of this file.
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_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines