BlockAllocator.h
上传用户:ghyvgy
上传日期:2009-05-26
资源大小:547k
文件大小:3k
源码类别:

其他游戏

开发平台:

Python

  1. //****************************************************************************
  2. //*    Author:  Tom C Gambill
  3. //*
  4. //*   Purpose:  Template for adding fixed size block allocator functionality 
  5. //* to a class. For MMP Game Gems
  6. //*
  7. //****************************************************************************
  8. #ifndef __BlockAllocator
  9. #define __BlockAllocator
  10. #include <vector>
  11. template <class T, size_t blocksPerBatch=100, size_t blockAlignment=4> class BlockAllocator
  12. {
  13. public:
  14. void* operator new(size_t)
  15. {
  16. return s_Store.AllocateBlock();
  17. }
  18. void operator delete(void* pBlock)
  19. {
  20. s_Store.ReleaseBlock((T*)pBlock);
  21. }
  22. //* These can be called directly, but be warned, the constructors 
  23. //* and destructors on the blocks will not be called!
  24. static T* AllocateBlock()  { return s_Store.AllocateBlock(); }
  25. static void ReleaseBlock(T* pBlock) { s_Store.ReleaseBlock(pBlock); }
  26. private:
  27. struct BlockStore
  28. {
  29. BlockStore() : ppNextBlock(0) {};
  30. ~BlockStore()
  31. {
  32. //* Check for memory leaks...
  33. // Must clean up these pointers
  34. size_t iNum = batches.size();
  35. for (size_t i=0; i<iNum; ++i)
  36. {
  37. byte* p = (byte*)batches[i];
  38. delete [] p;
  39. }
  40. }
  41. T* AllocateBlock()
  42. {
  43. //* Is there any room?
  44. if (!ppNextBlock || !*ppNextBlock)
  45. {
  46. // determine the allligned size of the blocks
  47. static const size_t blockSize = (sizeof(T)+blockAlignment-1)&(~(blockAlignment-1));
  48. // make a new batch 
  49. byte *pNewBatch = new byte[blocksPerBatch*blockSize+15];
  50. batches.push_back(pNewBatch);
  51. //* Align the block on a 16-byte boundary
  52. byte* pAlignedPtr =(byte*)((uint)(pNewBatch+15)&(~15));
  53. // fill the pointers with the new blocks
  54. ppNextBlock = (byte**)pAlignedPtr;
  55. for (int i=0; i<blocksPerBatch-1; ++i)
  56. {
  57. *((uint*)(pAlignedPtr + i*blockSize)) = (uint)(pAlignedPtr + (i+1)*blockSize);
  58. }
  59. *((uint*)(pAlignedPtr + (blocksPerBatch-1)*blockSize)) = (uint)0;
  60. }
  61. byte* pBlock = (byte*)ppNextBlock;
  62. ppNextBlock = (byte**)*ppNextBlock;
  63. return (T*)pBlock;
  64. }
  65. void ReleaseBlock(T* pBlock)
  66. {
  67. if(pBlock)
  68. {
  69. *((uint*)pBlock) = (uint)ppNextBlock;
  70. ppNextBlock = (byte**)((byte*)pBlock);
  71. }
  72. }
  73. typedef vector<byte*> BatchPtrVector;
  74. byte** ppNextBlock; // Pointer to the next available block pointer
  75. BatchPtrVector batches; // Array of pointers to batches
  76. };
  77. static BlockStore s_Store;
  78. };
  79. template<class T, size_t blocksPerBatch, size_t blockAlignment> BlockAllocator<T, blocksPerBatch, blockAlignment>::BlockStore BlockAllocator<T, blocksPerBatch, blockAlignment>::s_Store;
  80. #endif /* __BlockAllocator */