Cycles: Throw bad_alloc exception when custom allocators failed to allocate memory

This mimics behavior of default allocators in STL and allows all the routines
to catch out-of-memory exceptions and hopefully recover from that situation/
This commit is contained in:
Sergey Sharybin 2016-04-20 15:49:52 +02:00
parent d7e4f920fd
commit e3544c9e28
3 changed files with 26 additions and 7 deletions

View File

@ -53,19 +53,24 @@ public:
size_t size = n * sizeof(T); size_t size = n * sizeof(T);
util_guarded_mem_alloc(size); util_guarded_mem_alloc(size);
(void)hint; (void)hint;
#ifdef WITH_BLENDER_GUARDEDALLOC
if(n == 0) { if(n == 0) {
return NULL; return NULL;
} }
T *mem;
#ifdef WITH_BLENDER_GUARDEDALLOC
/* C++ standard requires allocation functions to allocate memory suitably /* C++ standard requires allocation functions to allocate memory suitably
* aligned for any standard type. This is 16 bytes for 64 bit platform as * 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 * far as i concerned. We might over-align on 32bit here, but that should
* be all safe actually. * be all safe actually.
*/ */
return (T*)MEM_mallocN_aligned(size, 16, "Cycles Alloc"); mem = (T*)MEM_mallocN_aligned(size, 16, "Cycles Alloc");
#else #else
return (T*)malloc(size); mem = (T*)malloc(size);
#endif #endif
if(mem == NULL) {
throw std::bad_alloc();
}
return mem;
} }
void deallocate(T *p, size_t n) void deallocate(T *p, size_t n)
@ -97,7 +102,9 @@ public:
void construct(T *p, const T& val) void construct(T *p, const T& val)
{ {
new ((T *)p) T(val); if(p != NULL) {
new ((T *)p) T(val);
}
} }
void destroy(T *p) void destroy(T *p)

View File

@ -60,11 +60,15 @@ public:
if(pointer_ + n >= SIZE) { if(pointer_ + n >= SIZE) {
size_t size = n * sizeof(T); size_t size = n * sizeof(T);
util_guarded_mem_alloc(size); util_guarded_mem_alloc(size);
T *mem;
#ifdef WITH_BLENDER_GUARDEDALLOC #ifdef WITH_BLENDER_GUARDEDALLOC
return (T*)MEM_mallocN_aligned(size, 16, "Cycles Alloc"); mem = (T*)MEM_mallocN_aligned(size, 16, "Cycles Alloc");
#else #else
return (T*)malloc(size); mem = (T*)malloc(size);
#endif #endif
if(mem == NULL) {
throw std::bad_alloc();
}
} }
T *mem = &data_[pointer_]; T *mem = &data_[pointer_];
pointer_ += n; pointer_ += n;
@ -104,7 +108,9 @@ public:
void construct(T *p, const T& val) void construct(T *p, const T& val)
{ {
new ((T *)p) T(val); if(p != NULL) {
new ((T *)p) T(val);
}
} }
void destroy(T *p) void destroy(T *p)

View File

@ -218,10 +218,16 @@ public:
protected: protected:
inline T* mem_allocate(size_t N) inline T* mem_allocate(size_t N)
{ {
if(N == 0) {
return NULL;
}
T *mem = (T*)util_aligned_malloc(sizeof(T)*N, alignment); T *mem = (T*)util_aligned_malloc(sizeof(T)*N, alignment);
if(mem != NULL) { if(mem != NULL) {
util_guarded_mem_alloc(sizeof(T)*N); util_guarded_mem_alloc(sizeof(T)*N);
} }
else {
throw std::bad_alloc();
}
return mem; return mem;
} }