util_stack_allocator.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright 2011-2016 Blender Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef __UTIL_STACK_ALLOCATOR_H__
  17. #define __UTIL_STACK_ALLOCATOR_H__
  18. #include <cstddef>
  19. #include <memory>
  20. CCL_NAMESPACE_BEGIN
  21. /* Stack allocator for the use with STL. */
  22. template<int SIZE, typename T> class ccl_try_align(16) StackAllocator
  23. {
  24. public:
  25. typedef size_t size_type;
  26. typedef ptrdiff_t difference_type;
  27. typedef T *pointer;
  28. typedef const T *const_pointer;
  29. typedef T &reference;
  30. typedef const T &const_reference;
  31. typedef T value_type;
  32. /* Allocator construction/destruction. */
  33. StackAllocator() : pointer_(0), use_stack_(true)
  34. {
  35. }
  36. StackAllocator(const StackAllocator &) : pointer_(0), use_stack_(true)
  37. {
  38. }
  39. template<class U>
  40. StackAllocator(const StackAllocator<SIZE, U> &) : pointer_(0), use_stack_(false)
  41. {
  42. }
  43. /* Memory allocation/deallocation. */
  44. T *allocate(size_t n, const void *hint = 0)
  45. {
  46. (void)hint;
  47. if (n == 0) {
  48. return NULL;
  49. }
  50. if (pointer_ + n >= SIZE || use_stack_ == false) {
  51. size_t size = n * sizeof(T);
  52. util_guarded_mem_alloc(size);
  53. T *mem;
  54. #ifdef WITH_BLENDER_GUARDEDALLOC
  55. mem = (T *)MEM_mallocN_aligned(size, 16, "Cycles Alloc");
  56. #else
  57. mem = (T *)malloc(size);
  58. #endif
  59. if (mem == NULL) {
  60. throw std::bad_alloc();
  61. }
  62. return mem;
  63. }
  64. T *mem = &data_[pointer_];
  65. pointer_ += n;
  66. return mem;
  67. }
  68. void deallocate(T * p, size_t n)
  69. {
  70. if (p == NULL) {
  71. return;
  72. }
  73. if (p < data_ || p >= data_ + SIZE) {
  74. util_guarded_mem_free(n * sizeof(T));
  75. #ifdef WITH_BLENDER_GUARDEDALLOC
  76. MEM_freeN(p);
  77. #else
  78. free(p);
  79. #endif
  80. return;
  81. }
  82. /* We don't support memory free for the stack allocator. */
  83. }
  84. /* Address of an reference. */
  85. T *address(T & x) const
  86. {
  87. return &x;
  88. }
  89. const T *address(const T &x) const
  90. {
  91. return &x;
  92. }
  93. /* Object construction/destruction. */
  94. void construct(T * p, const T &val)
  95. {
  96. if (p != NULL) {
  97. new ((T *)p) T(val);
  98. }
  99. }
  100. void destroy(T * p)
  101. {
  102. p->~T();
  103. }
  104. /* Maximum allocation size. */
  105. size_t max_size() const
  106. {
  107. return size_t(-1);
  108. }
  109. /* Rebind to other ype of allocator. */
  110. template<class U> struct rebind {
  111. typedef StackAllocator<SIZE, U> other;
  112. };
  113. /* Operators */
  114. template<class U> inline StackAllocator &operator=(const StackAllocator<SIZE, U> &)
  115. {
  116. return *this;
  117. }
  118. StackAllocator<SIZE, T> &operator=(const StackAllocator &)
  119. {
  120. return *this;
  121. }
  122. inline bool operator==(StackAllocator const & /*other*/) const
  123. {
  124. return true;
  125. }
  126. inline bool operator!=(StackAllocator const &other) const
  127. {
  128. return !operator==(other);
  129. }
  130. private:
  131. int pointer_;
  132. bool use_stack_;
  133. T data_[SIZE];
  134. };
  135. CCL_NAMESPACE_END
  136. #endif /* __UTIL_STACK_ALLOCATOR_H__ */