allocator.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /***********************************************************************
  2. * Software License Agreement (BSD License)
  3. *
  4. * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
  5. * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
  6. *
  7. * THE BSD LICENSE
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *************************************************************************/
  30. #ifndef OPENCV_FLANN_ALLOCATOR_H_
  31. #define OPENCV_FLANN_ALLOCATOR_H_
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. namespace cvflann
  35. {
  36. /**
  37. * Allocates (using C's malloc) a generic type T.
  38. *
  39. * Params:
  40. * count = number of instances to allocate.
  41. * Returns: pointer (of type T*) to memory buffer
  42. */
  43. template <typename T>
  44. T* allocate(size_t count = 1)
  45. {
  46. T* mem = (T*) ::malloc(sizeof(T)*count);
  47. return mem;
  48. }
  49. /**
  50. * Pooled storage allocator
  51. *
  52. * The following routines allow for the efficient allocation of storage in
  53. * small chunks from a specified pool. Rather than allowing each structure
  54. * to be freed individually, an entire pool of storage is freed at once.
  55. * This method has two advantages over just using malloc() and free(). First,
  56. * it is far more efficient for allocating small objects, as there is
  57. * no overhead for remembering all the information needed to free each
  58. * object or consolidating fragmented memory. Second, the decision about
  59. * how long to keep an object is made at the time of allocation, and there
  60. * is no need to track down all the objects to free them.
  61. *
  62. */
  63. const size_t WORDSIZE=16;
  64. const size_t BLOCKSIZE=8192;
  65. class PooledAllocator
  66. {
  67. /* We maintain memory alignment to word boundaries by requiring that all
  68. allocations be in multiples of the machine wordsize. */
  69. /* Size of machine word in bytes. Must be power of 2. */
  70. /* Minimum number of bytes requested at a time from the system. Must be multiple of WORDSIZE. */
  71. int remaining; /* Number of bytes left in current block of storage. */
  72. void* base; /* Pointer to base of current block of storage. */
  73. void* loc; /* Current location in block to next allocate memory. */
  74. int blocksize;
  75. public:
  76. int usedMemory;
  77. int wastedMemory;
  78. /**
  79. Default constructor. Initializes a new pool.
  80. */
  81. PooledAllocator(int blockSize = BLOCKSIZE)
  82. {
  83. blocksize = blockSize;
  84. remaining = 0;
  85. base = NULL;
  86. loc = NULL;
  87. usedMemory = 0;
  88. wastedMemory = 0;
  89. }
  90. /**
  91. * Destructor. Frees all the memory allocated in this pool.
  92. */
  93. ~PooledAllocator()
  94. {
  95. void* prev;
  96. while (base != NULL) {
  97. prev = *((void**) base); /* Get pointer to prev block. */
  98. ::free(base);
  99. base = prev;
  100. }
  101. }
  102. /**
  103. * Returns a pointer to a piece of new memory of the given size in bytes
  104. * allocated from the pool.
  105. */
  106. void* allocateMemory(int size)
  107. {
  108. int blockSize;
  109. /* Round size up to a multiple of wordsize. The following expression
  110. only works for WORDSIZE that is a power of 2, by masking last bits of
  111. incremented size to zero.
  112. */
  113. size = (size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
  114. /* Check whether a new block must be allocated. Note that the first word
  115. of a block is reserved for a pointer to the previous block.
  116. */
  117. if (size > remaining) {
  118. wastedMemory += remaining;
  119. /* Allocate new storage. */
  120. blockSize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ?
  121. size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE;
  122. // use the standard C malloc to allocate memory
  123. void* m = ::malloc(blockSize);
  124. if (!m) {
  125. fprintf(stderr,"Failed to allocate memory.\n");
  126. return NULL;
  127. }
  128. /* Fill first word of new block with pointer to previous block. */
  129. ((void**) m)[0] = base;
  130. base = m;
  131. int shift = 0;
  132. //int shift = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1);
  133. remaining = blockSize - sizeof(void*) - shift;
  134. loc = ((char*)m + sizeof(void*) + shift);
  135. }
  136. void* rloc = loc;
  137. loc = (char*)loc + size;
  138. remaining -= size;
  139. usedMemory += size;
  140. return rloc;
  141. }
  142. /**
  143. * Allocates (using this pool) a generic type T.
  144. *
  145. * Params:
  146. * count = number of instances to allocate.
  147. * Returns: pointer (of type T*) to memory buffer
  148. */
  149. template <typename T>
  150. T* allocate(size_t count = 1)
  151. {
  152. T* mem = (T*) this->allocateMemory((int)(sizeof(T)*count));
  153. return mem;
  154. }
  155. private:
  156. PooledAllocator(const PooledAllocator &); // copy disabled
  157. PooledAllocator& operator=(const PooledAllocator &); // assign disabled
  158. };
  159. }
  160. #endif //OPENCV_FLANN_ALLOCATOR_H_