PoolAllocator.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. //
  2. // "$Id$"
  3. //
  4. // Copyright (c)1992-2011, ZheJiang Dahua Technology Stock CO.LTD.
  5. // All Rights Reserved.
  6. //
  7. // Description:
  8. // 参考"The C++ Programming Laguage (Special Edition)", by Bjarne Stroustrup,
  9. // 实现的内存模式内存分配器
  10. // Revisions:
  11. // 2007-8-9 wang_haifeng Modification
  12. //
  13. #ifndef __INFRA_POOL_ALLOCATOR_H__
  14. #define __INFRA_POOL_ALLOCATOR_H__
  15. #include <cassert>
  16. #include <new>
  17. #include "Infra/Mutex.h"
  18. #include "Detail/singleton_pool.h"
  19. #include "Detail/MemPool.h"
  20. // 判断STL是否正确实现了 deallocate
  21. #if defined(_RWSTD_VER) || defined(__SGI_STL_PORT) || defined(__BORLANDC__)
  22. #define DAHUA_NO_PROPER_STL_DEALLOCATE
  23. #endif
  24. namespace Dahua {
  25. namespace Memory {
  26. ////////////////////////////////////////////////////////////////////////////////
  27. namespace Pool {
  28. struct DefaultMutex
  29. {
  30. Infra::CMutex m_mutex;
  31. void lock() {m_mutex.enter();}
  32. void unlock() {m_mutex.leave();}
  33. };
  34. struct NullMutex
  35. {
  36. void lock() {}
  37. void unlock() {}
  38. };
  39. struct PoolAllocatorTag {};
  40. } // namespace Pool
  41. ////////////////////////////////////////////////////////////////////////////////
  42. /// \brief 符合std:: alloctor定义的内存模式内存分配器
  43. ///
  44. /// - 只支持list容器, 因为list容器每次只申请或释放一个一种规格的节点. 对于deque,
  45. /// 当元素规格小于4K时, 其默认的申请策略就相当于内存池, 大于等于4K时, 会申请两
  46. /// 种类型的规格, 一种是元素指针, 一次申请的个数采用采用番倍策略, 另一种是元素,
  47. /// 这时才可以考虑内存池. 对vector使用池管理实在没什么意义, 其内存管理策略也
  48. /// 已经考虑了动态增长的情况, 如果非要用内存池实现, 将付出沉重代价.
  49. template <typename T,
  50. typename PoolType = Detail::CMemPool, // 指定内存池类型
  51. typename Mutex = Pool::NullMutex, // 指定锁类型, Detial::CMemPool 内部已经加锁,这里用 NullMutex
  52. unsigned nextSize = 64, // 每次分配的区块数
  53. unsigned maxSize = 0>
  54. class TPoolAllocator;
  55. /// \brief TPoolAllocator的偏特化版本
  56. template<
  57. typename PoolType,
  58. typename Mutex,
  59. unsigned nextSize,
  60. unsigned maxSize>
  61. class TPoolAllocator<void, PoolType, Mutex, nextSize, maxSize>
  62. {
  63. public:
  64. typedef void* pointer;
  65. typedef const void* const_pointer;
  66. typedef void value_type;
  67. template <class U> struct rebind {
  68. typedef TPoolAllocator<U, PoolType, Mutex, nextSize, maxSize> other;
  69. };
  70. };
  71. /// \brief 符合std:: alloctor定义的内存模式内存分配器
  72. /// 对象内存使用CMemPool管理,由于是静态变量,所以程序生命周期中申请到的系统内存一直不会释放
  73. template <typename T,
  74. typename PoolType,
  75. typename Mutex,
  76. unsigned nextSize,
  77. unsigned maxSize>
  78. class TPoolAllocator
  79. {
  80. public:
  81. typedef Mutex mutex_type;
  82. typedef PoolType pool_type;
  83. static const unsigned next_size = nextSize;
  84. typedef T value_type;
  85. typedef T * pointer;
  86. typedef const T * const_pointer;
  87. typedef T & reference;
  88. typedef const T & const_reference;
  89. typedef size_t size_type;
  90. typedef std::ptrdiff_t difference_type;
  91. template <typename U>
  92. struct rebind
  93. {
  94. typedef TPoolAllocator<U, PoolType, Mutex, nextSize, maxSize> other;
  95. };
  96. TPoolAllocator()
  97. {}
  98. template <class U>
  99. TPoolAllocator(TPoolAllocator<U, PoolType, Mutex, nextSize, maxSize> const&)
  100. {}
  101. ~TPoolAllocator()
  102. {}
  103. pointer address(reference x) const
  104. { return &x; }
  105. const_pointer address(const_reference x) const
  106. { return x; }
  107. bool operator==(const TPoolAllocator &) const
  108. { return true; }
  109. bool operator!=(const TPoolAllocator &) const
  110. { return false; }
  111. static pointer allocate(const size_type n)
  112. {
  113. typedef Detail::singleton_pool<Pool::PoolAllocatorTag, sizeof(T), PoolType, Mutex, nextSize, maxSize> SingletonPool;
  114. assert(n == 1);
  115. const pointer ret = static_cast<pointer>(SingletonPool::malloc());
  116. if (ret == 0)
  117. {
  118. throw std::bad_alloc();
  119. }
  120. return ret;
  121. }
  122. static pointer allocate(const size_type n, const void * const)
  123. { return allocate(n); }
  124. static void deallocate(const pointer ptr, const size_type n)
  125. {
  126. typedef Detail::singleton_pool<Pool::PoolAllocatorTag, sizeof(T), PoolType, Mutex, nextSize, maxSize> SingletonPool;
  127. #ifdef DAHUA_NO_PROPER_STL_DEALLOCATE
  128. if (ptr == 0 || n == 0) return;
  129. #endif
  130. assert(n == 1);
  131. SingletonPool::free(ptr);
  132. }
  133. size_type max_size() const
  134. {
  135. return static_cast<size_type>(-1) / sizeof(T);
  136. }
  137. void construct(pointer ptr, const value_type& x)
  138. {
  139. new(ptr) T(x);
  140. }
  141. void destroy(pointer ptr)
  142. {
  143. ptr->~T();
  144. (void) ptr; // avoid unused variable warning
  145. }
  146. };
  147. } // namespace Memory
  148. } // namespace Dahua
  149. #endif // __INFRA_POOL_ALLOCATOR_H__