diff options
Diffstat (limited to 'intern/cycles/util/util_guarded_allocator.h')
-rw-r--r-- | intern/cycles/util/util_guarded_allocator.h | 238 |
1 files changed, 124 insertions, 114 deletions
diff --git a/intern/cycles/util/util_guarded_allocator.h b/intern/cycles/util/util_guarded_allocator.h index 99edf77e2c7..2d09326d2ca 100644 --- a/intern/cycles/util/util_guarded_allocator.h +++ b/intern/cycles/util/util_guarded_allocator.h @@ -31,117 +31,127 @@ void util_guarded_mem_alloc(size_t n); void util_guarded_mem_free(size_t n); /* Guarded allocator for the use with STL. */ -template <typename T> -class GuardedAllocator { -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; - - GuardedAllocator() {} - GuardedAllocator(const GuardedAllocator&) {} - - T *allocate(size_t n, const void *hint = 0) - { - (void) hint; - size_t size = n * sizeof(T); - util_guarded_mem_alloc(size); - if(n == 0) { - return NULL; - } - T *mem; +template<typename T> class GuardedAllocator { + 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; + + GuardedAllocator() + { + } + GuardedAllocator(const GuardedAllocator &) + { + } + + T *allocate(size_t n, const void *hint = 0) + { + (void)hint; + size_t size = n * sizeof(T); + util_guarded_mem_alloc(size); + if (n == 0) { + return NULL; + } + T *mem; #ifdef WITH_BLENDER_GUARDEDALLOC - /* C++ standard requires allocation functions to allocate memory suitably - * aligned for any standard type. This is 16 bytes for 64 bit platform as - * far as i concerned. We might over-align on 32bit here, but that should - * be all safe actually. - */ - mem = (T*)MEM_mallocN_aligned(size, 16, "Cycles Alloc"); + /* C++ standard requires allocation functions to allocate memory suitably + * aligned for any standard type. This is 16 bytes for 64 bit platform as + * far as i concerned. We might over-align on 32bit here, but that should + * be all safe actually. + */ + mem = (T *)MEM_mallocN_aligned(size, 16, "Cycles Alloc"); #else - mem = (T*)malloc(size); + mem = (T *)malloc(size); #endif - if(mem == NULL) { - throw std::bad_alloc(); - } - return mem; - } - - void deallocate(T *p, size_t n) - { - util_guarded_mem_free(n * sizeof(T)); - if(p != NULL) { + if (mem == NULL) { + throw std::bad_alloc(); + } + return mem; + } + + void deallocate(T *p, size_t n) + { + util_guarded_mem_free(n * sizeof(T)); + if (p != NULL) { #ifdef WITH_BLENDER_GUARDEDALLOC - MEM_freeN(p); + MEM_freeN(p); #else - free(p); + free(p); #endif - } - } - - T *address(T& x) const - { - return &x; - } - - const T *address(const T& x) const - { - return &x; - } - - GuardedAllocator<T>& operator=(const GuardedAllocator&) - { - return *this; - } - - size_t max_size() const - { - return size_t(-1); - } - - template <class U> - struct rebind { - typedef GuardedAllocator<U> other; - }; - - template <class U> - GuardedAllocator(const GuardedAllocator<U>&) {} - - template <class U> - GuardedAllocator& operator=(const GuardedAllocator<U>&) { return *this; } - - inline bool operator==(GuardedAllocator const& /*other*/) const { return true; } - inline bool operator!=(GuardedAllocator const& other) const { return !operator==(other); } + } + } + + T *address(T &x) const + { + return &x; + } + + const T *address(const T &x) const + { + return &x; + } + + GuardedAllocator<T> &operator=(const GuardedAllocator &) + { + return *this; + } + + size_t max_size() const + { + return size_t(-1); + } + + template<class U> struct rebind { + typedef GuardedAllocator<U> other; + }; + + template<class U> GuardedAllocator(const GuardedAllocator<U> &) + { + } + + template<class U> GuardedAllocator &operator=(const GuardedAllocator<U> &) + { + return *this; + } + + inline bool operator==(GuardedAllocator const & /*other*/) const + { + return true; + } + inline bool operator!=(GuardedAllocator const &other) const + { + return !operator==(other); + } #ifdef _MSC_VER - /* Welcome to the black magic here. - * - * The issue is that MSVC C++ allocates container proxy on any - * vector initialization, including static vectors which don't - * have any data yet. This leads to several issues: - * - * - Static objects initialization fiasco (global_stats from - * util_stats.h might not be initialized yet). - * - If main() function changes allocator type (for example, - * this might happen with `blender --debug-memory`) nobody - * will know how to convert already allocated memory to a new - * guarded allocator. - * - * Here we work this around by making it so container proxy does - * not use guarded allocation. A bit fragile, unfortunately. - */ - template<> - struct rebind<std::_Container_proxy> { - typedef std::allocator<std::_Container_proxy> other; - }; - - operator std::allocator<std::_Container_proxy>() const - { - return std::allocator<std::_Container_proxy>(); - } + /* Welcome to the black magic here. + * + * The issue is that MSVC C++ allocates container proxy on any + * vector initialization, including static vectors which don't + * have any data yet. This leads to several issues: + * + * - Static objects initialization fiasco (global_stats from + * util_stats.h might not be initialized yet). + * - If main() function changes allocator type (for example, + * this might happen with `blender --debug-memory`) nobody + * will know how to convert already allocated memory to a new + * guarded allocator. + * + * Here we work this around by making it so container proxy does + * not use guarded allocation. A bit fragile, unfortunately. + */ + template<> struct rebind<std::_Container_proxy> { + typedef std::allocator<std::_Container_proxy> other; + }; + + operator std::allocator<std::_Container_proxy>() const + { + return std::allocator<std::_Container_proxy>(); + } #endif }; @@ -158,17 +168,17 @@ size_t util_guarded_get_mem_peak(); * when running out of memory. */ #define MEM_GUARDED_CALL(progress, func, ...) \ - do { \ - try { \ - (func)(__VA_ARGS__); \ - } \ - catch (std::bad_alloc&) { \ - fprintf(stderr, "Error: run out of memory!\n"); \ - fflush(stderr); \ - (progress)->set_error("Out of memory"); \ - } \ - } while(false) + do { \ + try { \ + (func)(__VA_ARGS__); \ + } \ + catch (std::bad_alloc &) { \ + fprintf(stderr, "Error: run out of memory!\n"); \ + fflush(stderr); \ + (progress)->set_error("Out of memory"); \ + } \ + } while (false) CCL_NAMESPACE_END -#endif /* __UTIL_GUARDED_ALLOCATOR_H__ */ +#endif /* __UTIL_GUARDED_ALLOCATOR_H__ */ |