33 #include "safe_refcount.h" 34 #include "os/memory_pool_dynamic.h" 35 #include "os/memory_pool_static.h" 47 MemoryPoolDynamic::ID id;
56 if (data->refcount.unref()) {
58 if (data->id!=MemoryPoolDynamic::INVALID_ID)
59 MemoryPoolDynamic::get_singleton()->free(data->id);
60 MemoryPoolStatic::get_singleton()->
free(data);
66 void ref(Data *p_data) {
72 if (p_data && p_data->refcount.ref())
80 if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
81 MemoryPoolDynamic::get_singleton()->lock(data->id);
83 inline void unlock() {
85 if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
86 MemoryPoolDynamic::get_singleton()->unlock(data->id);
92 if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
93 return MemoryPoolDynamic::get_singleton()->get(data->id);
98 Error _resize(
size_t p_size) {
100 if (p_size==0 && (!data || data->id==MemoryPoolDynamic::INVALID_ID))
102 if (p_size && !data) {
104 data = (Data*)MemoryPoolStatic::get_singleton()->
alloc(
sizeof(Data),
"MID::Data");
105 ERR_FAIL_COND_V( !data,ERR_OUT_OF_MEMORY );
106 data->refcount.init();
107 data->id=MemoryPoolDynamic::INVALID_ID;
110 if (p_size==0 && data && data->id==MemoryPoolDynamic::INVALID_ID) {
112 MemoryPoolDynamic::get_singleton()->free(data->id);
113 data->id=MemoryPoolDynamic::INVALID_ID;
118 if (data->id==MemoryPoolDynamic::INVALID_ID) {
120 data->id=MemoryPoolDynamic::get_singleton()->alloc(p_size,
"Unnamed MID");
121 ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
125 MemoryPoolDynamic::get_singleton()->realloc(data->id,p_size);
126 ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
135 MID(MemoryPoolDynamic::ID p_id) {
137 data = (Data*)MemoryPoolStatic::get_singleton()->
alloc(
sizeof(Data),
"MID::Data");
138 data->refcount.init();
143 bool is_valid()
const {
return data; }
144 operator bool()
const {
return data; }
147 size_t get_size()
const {
return (data && data->id!=MemoryPoolDynamic::INVALID_ID) ? MemoryPoolDynamic::get_singleton()->get_size(data->id) : 0; }
148 Error resize(
size_t p_size) {
return _resize(p_size); }
149 inline void operator=(
const MID& p_mid) { ref( p_mid.data ); }
150 inline bool is_locked()
const {
return (data && data->id!=MemoryPoolDynamic::INVALID_ID) ? MemoryPoolDynamic::get_singleton()->is_locked(data->id) :
false; }
151 inline MID(
const MID& p_mid) { data=NULL; ref( p_mid.data ); }
152 inline MID() { data = NULL; }
163 void *data() {
return mid.get(); }
165 void operator=(
const MID_Lock& p_lock ) { mid.unlock(); mid = p_lock.mid; mid.lock(); }
166 inline MID_Lock(
const MID& p_mid) { mid=p_mid; mid.lock(); }
178 static void * alloc_static(
size_t p_bytes,
const char *p_descr=
"");
179 static void * realloc_static(
void *p_memory,
size_t p_bytes);
180 static void free_static(
void *p_ptr);
181 static size_t get_static_mem_available();
182 static size_t get_static_mem_usage();
183 static size_t get_static_mem_max_usage();
184 static void dump_static_mem_to_file(
const char* p_file);
186 static MID alloc_dynamic(
size_t p_bytes,
const char *p_descr=
"");
187 static Error realloc_dynamic(
MID p_mid,
size_t p_bytes);
189 static size_t get_dynamic_mem_available();
190 static size_t get_dynamic_mem_usage();
196 static _FORCE_INLINE_
int get_align() {
return DEFAULT_ALIGNMENT; }
201 _FORCE_INLINE_
static void *alloc(
size_t p_memory) {
return Memory::alloc_static(p_memory,
""); }
202 _FORCE_INLINE_
static void free(
void *p_ptr) {
return Memory::free_static(p_ptr); }
207 void *
operator new(
size_t p_size,
const char *p_description);
208 void *
operator new(
size_t p_size,
void* (*p_allocfunc)(
size_t p_size));
210 void *
operator new(
size_t p_size,
void *p_pointer,
size_t check,
const char *p_description);
212 #ifdef DEBUG_MEMORY_ENABLED 214 #define memalloc(m_size) Memory::alloc_static(m_size, __FILE__ ":" __STR(__LINE__) ", memalloc.") 215 #define memrealloc(m_mem,m_size) Memory::realloc_static(m_mem,m_size) 216 #define memfree(m_size) Memory::free_static(m_size) 220 #define memalloc(m_size) Memory::alloc_static(m_size) 221 #define memrealloc(m_mem,m_size) Memory::realloc_static(m_mem,m_size) 222 #define memfree(m_size) Memory::free_static(m_size) 226 #ifdef DEBUG_MEMORY_ENABLED 227 #define dynalloc(m_size) Memory::alloc_dynamic(m_size, __FILE__ ":" __STR(__LINE__) ", type: DYNAMIC") 228 #define dynrealloc(m_mem,m_size) m_mem.resize(m_size) 232 #define dynalloc(m_size) Memory::alloc_dynamic(m_size) 233 #define dynrealloc(m_mem,m_size) m_mem.resize(m_size) 238 _ALWAYS_INLINE_
void postinitialize_handler(
void *) {}
242 _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
244 postinitialize_handler(p_obj);
248 #ifdef DEBUG_MEMORY_ENABLED 250 #define memnew(m_class) _post_initialize(new(__FILE__ ":" __STR(__LINE__) ", memnew type: " __STR(m_class)) m_class) 254 #define memnew(m_class) _post_initialize(new("") m_class) 258 _ALWAYS_INLINE_
void *
operator new(
size_t p_size,
void *p_pointer,
size_t check,
const char *p_description) {
266 #define memnew_allocator(m_class,m_allocator) _post_initialize(new(m_allocator::alloc) m_class) 267 #define memnew_placement(m_placement,m_class) _post_initialize(new(m_placement,sizeof(m_class),"") m_class) 270 _ALWAYS_INLINE_
bool predelete_handler(
void *) {
return true; }
273 void memdelete(T *p_class) {
275 if (!predelete_handler(p_class))
278 Memory::free_static(p_class);
281 template<
class T,
class A>
282 void memdelete_allocator(T *p_class) {
284 if (!predelete_handler(p_class))
290 #define memdelete_notnull(m_v) { if (m_v) memdelete(m_v); } 291 #ifdef DEBUG_MEMORY_ENABLED 293 #define memnew_arr( m_class, m_count ) memnew_arr_template<m_class>(m_count,__FILE__ ":" __STR(__LINE__) ", memnew_arr type: " _STR(m_class)) 297 #define memnew_arr( m_class, m_count ) memnew_arr_template<m_class>(m_count) 302 T* memnew_arr_template(
size_t p_elements,
const char *p_descr=
"") {
309 size_t len =
sizeof(T) * p_elements;
310 unsigned int *mem = (
unsigned int*)Memory::alloc_static( len + MAX(
sizeof(
size_t), DEFAULT_ALIGNMENT), p_descr );
312 ERR_FAIL_COND_V( !mem, failptr );
314 mem = (
unsigned int *)( ((uint8_t*)mem) + MAX(
sizeof(
size_t), DEFAULT_ALIGNMENT));
318 for (
size_t i=0;i<p_elements;i++) {
319 new(&elems[i],
sizeof(T),p_descr) T;
331 size_t memarr_len(
const T *p_class) {
333 uint8_t* ptr = ((uint8_t*)p_class) - MAX(
sizeof(
size_t), DEFAULT_ALIGNMENT);
334 return *(
size_t*)ptr;
338 void memdelete_arr(T *p_class) {
340 unsigned int * elems = (
unsigned int*)(((uint8_t*)p_class) - MAX(
sizeof(
size_t), DEFAULT_ALIGNMENT));
342 for (
unsigned int i=0;i<*elems;i++) {
346 Memory::free_static(elems);
Definition: safe_refcount.h:336
virtual void * alloc(size_t p_bytes, const char *p_description)=0
Pointer in p_description shold be to a const char const like "hello".
virtual void free(void *p_ptr)=0
Pointer in p_description shold be to a const char const.