mem_in_use can be victim to C++ name mangling on some platforms...
[blender.git] / intern / memutil / intern / MEM_CacheLimiterC-Api.cpp
1 /**
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version. The Blender
6  * Foundation also sells licenses for use in proprietary software under
7  * the Blender License.  See http://www.blender.org/BL/ for information
8  * about this.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * Contributor(s): Peter Schlaile <peter@schlaile.de> 2005
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "MEM_CacheLimiter.h"
28 #include "MEM_CacheLimiterC-Api.h"
29
30 static int & get_max() 
31 {
32         static int m = 32*1024*1024;
33         return m;
34 }
35
36 void MEM_CacheLimiter_set_maximum(int m)
37 {
38         get_max() = m;
39 }
40
41 int MEM_CacheLimiter_get_maximum()
42 {
43         return get_max();
44 }
45
46 class MEM_CacheLimiterHandleCClass;
47 class MEM_CacheLimiterCClass;
48
49 typedef MEM_CacheLimiterHandle<MEM_CacheLimiterHandleCClass> handle_t;
50 typedef MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache_t;
51 typedef std::list<MEM_CacheLimiterHandleCClass*,
52                   MEM_Allocator<MEM_CacheLimiterHandleCClass* > > list_t;
53
54 class MEM_CacheLimiterCClass {
55 public:
56         MEM_CacheLimiterCClass(void (*data_destructor_) (void * data))
57                 : data_destructor(data_destructor_) { 
58         }
59         ~MEM_CacheLimiterCClass();
60         
61         handle_t * insert(void * data);
62
63         void destruct(void * data,
64                       list_t::iterator it);
65
66         cache_t * get_cache() {
67                 return &cache;
68         }
69 private:
70         void (*data_destructor) (void * data);
71
72         MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache;
73         
74         list_t cclass_list;
75 };
76
77 class MEM_CacheLimiterHandleCClass {
78 public:
79         MEM_CacheLimiterHandleCClass(void * data_,
80                                    MEM_CacheLimiterCClass * parent_)
81                 : data(data_), parent(parent_) { }
82         ~MEM_CacheLimiterHandleCClass();
83         void set_iter(list_t::iterator it_) {
84                 it = it_;
85         }
86         void set_data(void * data_) {
87                 data = data_;
88         }
89         void * get_data() const {
90                 return data;
91         }
92 private:
93         void * data;
94         MEM_CacheLimiterCClass * parent;
95         list_t::iterator it;
96 };
97
98 handle_t * MEM_CacheLimiterCClass::insert(void * data) 
99 {
100         cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this));
101         list_t::iterator it = cclass_list.end();
102         --it;
103         cclass_list.back()->set_iter(it);
104         
105         return cache.insert(cclass_list.back());
106 }
107
108 void MEM_CacheLimiterCClass::destruct(void * data, list_t::iterator it) 
109 {
110         data_destructor(data);
111         cclass_list.erase(it);
112 }
113
114 MEM_CacheLimiterHandleCClass::~MEM_CacheLimiterHandleCClass()
115 {
116         if (data) {
117                 parent->destruct(data, it);
118         }
119 }
120
121 MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass()
122 {
123         // should not happen, but don't leak memory in this case...
124         for (list_t::iterator it = cclass_list.begin();
125              it != cclass_list.end(); it++) {
126                 (*it)->set_data(0);
127                 delete *it;
128         }
129 }
130
131 // ----------------------------------------------------------------------
132
133 static inline MEM_CacheLimiterCClass* cast(MEM_CacheLimiterC * l)
134 {
135         return (MEM_CacheLimiterCClass*) l;
136 }
137
138 static inline handle_t* cast(MEM_CacheLimiterHandleC * l)
139 {
140         return (handle_t*) l;
141 }
142
143 MEM_CacheLimiterC * new_MEM_CacheLimiter(
144         void (*data_destructor) (void * data))
145 {
146         return (MEM_CacheLimiterC*) new MEM_CacheLimiterCClass(
147                 data_destructor);
148 }
149
150 void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This)
151 {
152         delete cast(This);
153 }
154
155 MEM_CacheLimiterHandleC * MEM_CacheLimiter_insert(
156         MEM_CacheLimiterC * This, void * data)
157 {
158         return (MEM_CacheLimiterHandleC *) cast(This)->insert(data);
159 }
160
161 void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC * This)
162 {
163         cast(This)->get_cache()->enforce_limits();
164 }
165         
166 void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC * handle)
167 {
168         cast(handle)->unmanage();
169 }
170         
171 void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC * handle)
172 {
173         cast(handle)->touch();
174 }
175         
176 void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC * handle)
177 {
178         cast(handle)->ref();
179 }
180         
181 void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC * handle)
182 {
183         cast(handle)->unref();
184 }
185
186 int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC * handle)
187 {
188         return cast(handle)->get_refcount();
189 }
190
191         
192 void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC * handle)
193 {
194         return cast(handle)->get()->get_data();
195 }