ClangFormat: apply to source, most of intern
[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.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup memutil
19  */
20
21 #include <cstddef>
22
23 #include "MEM_CacheLimiter.h"
24 #include "MEM_CacheLimiterC-Api.h"
25
26 static bool is_disabled = false;
27
28 static size_t &get_max()
29 {
30   static size_t m = 32 * 1024 * 1024;
31   return m;
32 }
33
34 void MEM_CacheLimiter_set_maximum(size_t m)
35 {
36   get_max() = m;
37 }
38
39 size_t MEM_CacheLimiter_get_maximum()
40 {
41   return get_max();
42 }
43
44 void MEM_CacheLimiter_set_disabled(bool disabled)
45 {
46   is_disabled = disabled;
47 }
48
49 bool MEM_CacheLimiter_is_disabled(void)
50 {
51   return is_disabled;
52 }
53
54 class MEM_CacheLimiterHandleCClass;
55 class MEM_CacheLimiterCClass;
56
57 typedef MEM_CacheLimiterHandle<MEM_CacheLimiterHandleCClass> handle_t;
58 typedef MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache_t;
59 typedef std::list<MEM_CacheLimiterHandleCClass *, MEM_Allocator<MEM_CacheLimiterHandleCClass *>>
60     list_t;
61
62 class MEM_CacheLimiterCClass {
63  public:
64   MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_,
65                          MEM_CacheLimiter_DataSize_Func data_size)
66       : data_destructor(data_destructor_), cache(data_size)
67   {
68   }
69   ~MEM_CacheLimiterCClass();
70
71   handle_t *insert(void *data);
72
73   void destruct(void *data, list_t::iterator it);
74
75   cache_t *get_cache()
76   {
77     return &cache;
78   }
79
80  private:
81   MEM_CacheLimiter_Destruct_Func data_destructor;
82
83   MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache;
84
85   list_t cclass_list;
86 };
87
88 class MEM_CacheLimiterHandleCClass {
89  public:
90   MEM_CacheLimiterHandleCClass(void *data_, MEM_CacheLimiterCClass *parent_)
91       : data(data_), parent(parent_)
92   {
93   }
94
95   ~MEM_CacheLimiterHandleCClass();
96
97   void set_iter(list_t::iterator it_)
98   {
99     it = it_;
100   }
101
102   void set_data(void *data_)
103   {
104     data = data_;
105   }
106
107   void *get_data() const
108   {
109     return data;
110   }
111
112  private:
113   void *data;
114   MEM_CacheLimiterCClass *parent;
115   list_t::iterator it;
116 };
117
118 handle_t *MEM_CacheLimiterCClass::insert(void *data)
119 {
120   cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this));
121   list_t::iterator it = cclass_list.end();
122   --it;
123   cclass_list.back()->set_iter(it);
124
125   return cache.insert(cclass_list.back());
126 }
127
128 void MEM_CacheLimiterCClass::destruct(void *data, list_t::iterator it)
129 {
130   data_destructor(data);
131   cclass_list.erase(it);
132 }
133
134 MEM_CacheLimiterHandleCClass::~MEM_CacheLimiterHandleCClass()
135 {
136   if (data) {
137     parent->destruct(data, it);
138   }
139 }
140
141 MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass()
142 {
143   // should not happen, but don't leak memory in this case...
144   for (list_t::iterator it = cclass_list.begin(); it != cclass_list.end(); it++) {
145     (*it)->set_data(NULL);
146
147     delete *it;
148   }
149 }
150
151 // ----------------------------------------------------------------------
152
153 static inline MEM_CacheLimiterCClass *cast(MEM_CacheLimiterC *l)
154 {
155   return (MEM_CacheLimiterCClass *)l;
156 }
157
158 static inline handle_t *cast(MEM_CacheLimiterHandleC *l)
159 {
160   return (handle_t *)l;
161 }
162
163 MEM_CacheLimiterC *new_MEM_CacheLimiter(MEM_CacheLimiter_Destruct_Func data_destructor,
164                                         MEM_CacheLimiter_DataSize_Func data_size)
165 {
166   return (MEM_CacheLimiterC *)new MEM_CacheLimiterCClass(data_destructor, data_size);
167 }
168
169 void delete_MEM_CacheLimiter(MEM_CacheLimiterC *This)
170 {
171   delete cast(This);
172 }
173
174 MEM_CacheLimiterHandleC *MEM_CacheLimiter_insert(MEM_CacheLimiterC *This, void *data)
175 {
176   return (MEM_CacheLimiterHandleC *)cast(This)->insert(data);
177 }
178
179 void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC *This)
180 {
181   cast(This)->get_cache()->enforce_limits();
182 }
183
184 void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC *handle)
185 {
186   cast(handle)->unmanage();
187 }
188
189 void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC *handle)
190 {
191   cast(handle)->touch();
192 }
193
194 void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC *handle)
195 {
196   cast(handle)->ref();
197 }
198
199 void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC *handle)
200 {
201   cast(handle)->unref();
202 }
203
204 int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC *handle)
205 {
206   return cast(handle)->get_refcount();
207 }
208
209 void *MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle)
210 {
211   return cast(handle)->get()->get_data();
212 }
213
214 void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
215                                             MEM_CacheLimiter_ItemPriority_Func item_priority_func)
216 {
217   cast(This)->get_cache()->set_item_priority_func(item_priority_func);
218 }
219
220 void MEM_CacheLimiter_ItemDestroyable_Func_set(
221     MEM_CacheLimiterC *This, MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func)
222 {
223   cast(This)->get_cache()->set_item_destroyable_func(item_destroyable_func);
224 }
225
226 size_t MEM_CacheLimiter_get_memory_in_use(MEM_CacheLimiterC *This)
227 {
228   return cast(This)->get_cache()->get_memory_in_use();
229 }