diff options
Diffstat (limited to 'intern/cycles/util/stack_allocator.h')
-rw-r--r-- | intern/cycles/util/stack_allocator.h | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/intern/cycles/util/stack_allocator.h b/intern/cycles/util/stack_allocator.h new file mode 100644 index 00000000000..ef31c0fe5e2 --- /dev/null +++ b/intern/cycles/util/stack_allocator.h @@ -0,0 +1,165 @@ +/* + * Copyright 2011-2016 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTIL_STACK_ALLOCATOR_H__ +#define __UTIL_STACK_ALLOCATOR_H__ + +#include <cstddef> +#include <memory> + +CCL_NAMESPACE_BEGIN + +/* Stack allocator for the use with STL. */ +template<int SIZE, typename T> class ccl_try_align(16) StackAllocator +{ + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T *pointer; + typedef const T *const_pointer; + typedef T &reference; + typedef const T &const_reference; + typedef T value_type; + + /* Allocator construction/destruction. */ + + StackAllocator() : pointer_(0), use_stack_(true) + { + } + + StackAllocator(const StackAllocator &) : pointer_(0), use_stack_(true) + { + } + + template<class U> + StackAllocator(const StackAllocator<SIZE, U> &) : pointer_(0), use_stack_(false) + { + } + + /* Memory allocation/deallocation. */ + + T *allocate(size_t n, const void *hint = 0) + { + (void)hint; + if (n == 0) { + return NULL; + } + if (pointer_ + n >= SIZE || use_stack_ == false) { + size_t size = n * sizeof(T); + util_guarded_mem_alloc(size); + T *mem; +#ifdef WITH_BLENDER_GUARDEDALLOC + mem = (T *)MEM_mallocN_aligned(size, 16, "Cycles Alloc"); +#else + mem = (T *)malloc(size); +#endif + if (mem == NULL) { + throw std::bad_alloc(); + } + return mem; + } + T *mem = &data_[pointer_]; + pointer_ += n; + return mem; + } + + void deallocate(T * p, size_t n) + { + if (p == NULL) { + return; + } + if (p < data_ || p >= data_ + SIZE) { + util_guarded_mem_free(n * sizeof(T)); +#ifdef WITH_BLENDER_GUARDEDALLOC + MEM_freeN(p); +#else + free(p); +#endif + return; + } + /* We don't support memory free for the stack allocator. */ + } + + /* Address of an reference. */ + + T *address(T & x) const + { + return &x; + } + + const T *address(const T &x) const + { + return &x; + } + + /* Object construction/destruction. */ + + void construct(T * p, const T &val) + { + if (p != NULL) { + new ((T *)p) T(val); + } + } + + void destroy(T * p) + { + p->~T(); + } + + /* Maximum allocation size. */ + + size_t max_size() const + { + return size_t(-1); + } + + /* Rebind to other type of allocator. */ + + template<class U> struct rebind { + typedef StackAllocator<SIZE, U> other; + }; + + /* Operators */ + + template<class U> inline StackAllocator &operator=(const StackAllocator<SIZE, U> &) + { + return *this; + } + + StackAllocator<SIZE, T> &operator=(const StackAllocator &) + { + return *this; + } + + inline bool operator==(StackAllocator const & /*other*/) const + { + return true; + } + + inline bool operator!=(StackAllocator const &other) const + { + return !operator==(other); + } + + private: + int pointer_; + bool use_stack_; + T data_[SIZE]; +}; + +CCL_NAMESPACE_END + +#endif /* __UTIL_STACK_ALLOCATOR_H__ */ |