|
Blender
V2.59
|
00001 00026 #include <cstddef> 00027 00028 #include "MEM_CacheLimiter.h" 00029 #include "MEM_CacheLimiterC-Api.h" 00030 00031 static intptr_t & get_max() 00032 { 00033 static intptr_t m = 32*1024*1024; 00034 return m; 00035 } 00036 00037 void MEM_CacheLimiter_set_maximum(intptr_t m) 00038 { 00039 get_max() = m; 00040 } 00041 00042 intptr_t MEM_CacheLimiter_get_maximum() 00043 { 00044 return get_max(); 00045 } 00046 00047 class MEM_CacheLimiterHandleCClass; 00048 class MEM_CacheLimiterCClass; 00049 00050 typedef MEM_CacheLimiterHandle<MEM_CacheLimiterHandleCClass> handle_t; 00051 typedef MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache_t; 00052 typedef std::list<MEM_CacheLimiterHandleCClass*, 00053 MEM_Allocator<MEM_CacheLimiterHandleCClass* > > list_t; 00054 00055 class MEM_CacheLimiterCClass { 00056 public: 00057 MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_) 00058 : data_destructor(data_destructor_) { 00059 } 00060 ~MEM_CacheLimiterCClass(); 00061 00062 handle_t * insert(void * data); 00063 00064 void destruct(void * data, 00065 list_t::iterator it); 00066 00067 cache_t * get_cache() { 00068 return &cache; 00069 } 00070 private: 00071 MEM_CacheLimiter_Destruct_Func data_destructor; 00072 00073 MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache; 00074 00075 list_t cclass_list; 00076 }; 00077 00078 class MEM_CacheLimiterHandleCClass { 00079 public: 00080 MEM_CacheLimiterHandleCClass(void * data_, 00081 MEM_CacheLimiterCClass * parent_) 00082 : data(data_), parent(parent_) { } 00083 ~MEM_CacheLimiterHandleCClass(); 00084 void set_iter(list_t::iterator it_) { 00085 it = it_; 00086 } 00087 void set_data(void * data_) { 00088 data = data_; 00089 } 00090 void * get_data() const { 00091 return data; 00092 } 00093 private: 00094 void * data; 00095 MEM_CacheLimiterCClass * parent; 00096 list_t::iterator it; 00097 }; 00098 00099 handle_t * MEM_CacheLimiterCClass::insert(void * data) 00100 { 00101 cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this)); 00102 list_t::iterator it = cclass_list.end(); 00103 --it; 00104 cclass_list.back()->set_iter(it); 00105 00106 return cache.insert(cclass_list.back()); 00107 } 00108 00109 void MEM_CacheLimiterCClass::destruct(void * data, list_t::iterator it) 00110 { 00111 data_destructor(data); 00112 cclass_list.erase(it); 00113 } 00114 00115 MEM_CacheLimiterHandleCClass::~MEM_CacheLimiterHandleCClass() 00116 { 00117 if (data) { 00118 parent->destruct(data, it); 00119 } 00120 } 00121 00122 MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass() 00123 { 00124 // should not happen, but don't leak memory in this case... 00125 for (list_t::iterator it = cclass_list.begin(); 00126 it != cclass_list.end(); it++) { 00127 (*it)->set_data(0); 00128 delete *it; 00129 } 00130 } 00131 00132 // ---------------------------------------------------------------------- 00133 00134 static inline MEM_CacheLimiterCClass* cast(MEM_CacheLimiterC * l) 00135 { 00136 return (MEM_CacheLimiterCClass*) l; 00137 } 00138 00139 static inline handle_t* cast(MEM_CacheLimiterHandleC * l) 00140 { 00141 return (handle_t*) l; 00142 } 00143 00144 MEM_CacheLimiterC * new_MEM_CacheLimiter( 00145 MEM_CacheLimiter_Destruct_Func data_destructor) 00146 { 00147 return (MEM_CacheLimiterC*) new MEM_CacheLimiterCClass( 00148 data_destructor); 00149 } 00150 00151 void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This) 00152 { 00153 delete cast(This); 00154 } 00155 00156 MEM_CacheLimiterHandleC * MEM_CacheLimiter_insert( 00157 MEM_CacheLimiterC * This, void * data) 00158 { 00159 return (MEM_CacheLimiterHandleC *) cast(This)->insert(data); 00160 } 00161 00162 void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC * This) 00163 { 00164 cast(This)->get_cache()->enforce_limits(); 00165 } 00166 00167 void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC * handle) 00168 { 00169 cast(handle)->unmanage(); 00170 } 00171 00172 void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC * handle) 00173 { 00174 cast(handle)->touch(); 00175 } 00176 00177 void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC * handle) 00178 { 00179 cast(handle)->ref(); 00180 } 00181 00182 void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC * handle) 00183 { 00184 cast(handle)->unref(); 00185 } 00186 00187 int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC * handle) 00188 { 00189 return cast(handle)->get_refcount(); 00190 } 00191 00192 00193 void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC * handle) 00194 { 00195 return cast(handle)->get()->get_data(); 00196 }