Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Peter Schlaile <peter@schlaile.de> 2005 00019 * 00020 * ***** BEGIN GPL LICENSE BLOCK ***** 00021 */ 00022 00027 #include <cstddef> 00028 00029 #include "MEM_CacheLimiter.h" 00030 #include "MEM_CacheLimiterC-Api.h" 00031 00032 static intptr_t & get_max() 00033 { 00034 static intptr_t m = 32*1024*1024; 00035 return m; 00036 } 00037 00038 void MEM_CacheLimiter_set_maximum(intptr_t m) 00039 { 00040 get_max() = m; 00041 } 00042 00043 intptr_t MEM_CacheLimiter_get_maximum() 00044 { 00045 return get_max(); 00046 } 00047 00048 class MEM_CacheLimiterHandleCClass; 00049 class MEM_CacheLimiterCClass; 00050 00051 typedef MEM_CacheLimiterHandle<MEM_CacheLimiterHandleCClass> handle_t; 00052 typedef MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache_t; 00053 typedef std::list<MEM_CacheLimiterHandleCClass*, 00054 MEM_Allocator<MEM_CacheLimiterHandleCClass* > > list_t; 00055 00056 class MEM_CacheLimiterCClass { 00057 public: 00058 MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_, MEM_CacheLimiter_DataSize_Func data_size) 00059 : data_destructor(data_destructor_), cache(data_size) { 00060 } 00061 ~MEM_CacheLimiterCClass(); 00062 00063 handle_t * insert(void * data); 00064 00065 void destruct(void * data, 00066 list_t::iterator it); 00067 00068 cache_t * get_cache() { 00069 return &cache; 00070 } 00071 private: 00072 MEM_CacheLimiter_Destruct_Func data_destructor; 00073 00074 MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache; 00075 00076 list_t cclass_list; 00077 }; 00078 00079 class MEM_CacheLimiterHandleCClass { 00080 public: 00081 MEM_CacheLimiterHandleCClass(void * data_, 00082 MEM_CacheLimiterCClass * parent_) 00083 : data(data_), parent(parent_) { } 00084 ~MEM_CacheLimiterHandleCClass(); 00085 void set_iter(list_t::iterator it_) { 00086 it = it_; 00087 } 00088 void set_data(void * data_) { 00089 data = data_; 00090 } 00091 void * get_data() const { 00092 return data; 00093 } 00094 private: 00095 void * data; 00096 MEM_CacheLimiterCClass * parent; 00097 list_t::iterator it; 00098 }; 00099 00100 handle_t * MEM_CacheLimiterCClass::insert(void * data) 00101 { 00102 cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this)); 00103 list_t::iterator it = cclass_list.end(); 00104 --it; 00105 cclass_list.back()->set_iter(it); 00106 00107 return cache.insert(cclass_list.back()); 00108 } 00109 00110 void MEM_CacheLimiterCClass::destruct(void * data, list_t::iterator it) 00111 { 00112 data_destructor(data); 00113 cclass_list.erase(it); 00114 } 00115 00116 MEM_CacheLimiterHandleCClass::~MEM_CacheLimiterHandleCClass() 00117 { 00118 if (data) { 00119 parent->destruct(data, it); 00120 } 00121 } 00122 00123 MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass() 00124 { 00125 // should not happen, but don't leak memory in this case... 00126 for (list_t::iterator it = cclass_list.begin(); 00127 it != cclass_list.end(); it++) { 00128 (*it)->set_data(0); 00129 delete *it; 00130 } 00131 } 00132 00133 // ---------------------------------------------------------------------- 00134 00135 static inline MEM_CacheLimiterCClass* cast(MEM_CacheLimiterC * l) 00136 { 00137 return (MEM_CacheLimiterCClass*) l; 00138 } 00139 00140 static inline handle_t* cast(MEM_CacheLimiterHandleC * l) 00141 { 00142 return (handle_t*) l; 00143 } 00144 00145 MEM_CacheLimiterC * new_MEM_CacheLimiter( 00146 MEM_CacheLimiter_Destruct_Func data_destructor, 00147 MEM_CacheLimiter_DataSize_Func data_size) 00148 { 00149 return (MEM_CacheLimiterC*) new MEM_CacheLimiterCClass( 00150 data_destructor, 00151 data_size); 00152 } 00153 00154 void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This) 00155 { 00156 delete cast(This); 00157 } 00158 00159 MEM_CacheLimiterHandleC * MEM_CacheLimiter_insert( 00160 MEM_CacheLimiterC * This, void * data) 00161 { 00162 return (MEM_CacheLimiterHandleC *) cast(This)->insert(data); 00163 } 00164 00165 void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC * This) 00166 { 00167 cast(This)->get_cache()->enforce_limits(); 00168 } 00169 00170 void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC * handle) 00171 { 00172 cast(handle)->unmanage(); 00173 } 00174 00175 void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC * handle) 00176 { 00177 cast(handle)->touch(); 00178 } 00179 00180 void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC * handle) 00181 { 00182 cast(handle)->ref(); 00183 } 00184 00185 void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC * handle) 00186 { 00187 cast(handle)->unref(); 00188 } 00189 00190 int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC * handle) 00191 { 00192 return cast(handle)->get_refcount(); 00193 } 00194 00195 00196 void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC * handle) 00197 { 00198 return cast(handle)->get()->get_data(); 00199 }