Adds generic memcache limitor (used by the new sequencer to cache
only a certain amount of frames).
This commit is contained in:
89
intern/memutil/MEM_Allocator.h
Normal file
89
intern/memutil/MEM_Allocator.h
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contributor(s): Peter Schlaile <peter@schlaile.de> 2005
|
||||||
|
*
|
||||||
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MEM_Allocator_h_included__
|
||||||
|
#define __MEM_Allocator_h_included__ 1
|
||||||
|
|
||||||
|
#include "guardedalloc/MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
template<typename _Tp>
|
||||||
|
struct MEM_Allocator
|
||||||
|
{
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef _Tp* pointer;
|
||||||
|
typedef const _Tp* const_pointer;
|
||||||
|
typedef _Tp& reference;
|
||||||
|
typedef const _Tp& const_reference;
|
||||||
|
typedef _Tp value_type;
|
||||||
|
|
||||||
|
template<typename _Tp1>
|
||||||
|
struct rebind {
|
||||||
|
typedef MEM_Allocator<_Tp1> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
MEM_Allocator() throw() {}
|
||||||
|
MEM_Allocator(const MEM_Allocator& __a) throw() {}
|
||||||
|
|
||||||
|
template<typename _Tp1>
|
||||||
|
MEM_Allocator(const MEM_Allocator<_Tp1> __a) throw() { }
|
||||||
|
|
||||||
|
~MEM_Allocator() throw() {}
|
||||||
|
|
||||||
|
pointer address(reference __x) const { return &__x; }
|
||||||
|
|
||||||
|
const_pointer address(const_reference __x) const { return &__x; }
|
||||||
|
|
||||||
|
// NB: __n is permitted to be 0. The C++ standard says nothing
|
||||||
|
// about what the return value is when __n == 0.
|
||||||
|
_Tp* allocate(size_type __n, const void* = 0) {
|
||||||
|
_Tp* __ret = 0;
|
||||||
|
if (__n)
|
||||||
|
__ret = static_cast<_Tp*>(
|
||||||
|
MEM_mallocN(__n * sizeof(_Tp),
|
||||||
|
"STL MEM_Allocator"));
|
||||||
|
return __ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// __p is not permitted to be a null pointer.
|
||||||
|
void deallocate(pointer __p, size_type){
|
||||||
|
MEM_freeN(__p);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type max_size() const throw() {
|
||||||
|
return size_t(-1) / sizeof(_Tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void construct(pointer __p, const _Tp& __val) {
|
||||||
|
new(__p) _Tp(__val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(pointer __p) {
|
||||||
|
__p->~_Tp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
170
intern/memutil/MEM_CacheLimiter.h
Normal file
170
intern/memutil/MEM_CacheLimiter.h
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contributor(s): Peter Schlaile <peter@schlaile.de> 2005
|
||||||
|
*
|
||||||
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MEM_cache_limiter_h_included__
|
||||||
|
#define __MEM_cache_limiter_h_included__ 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @section MEM_CacheLimiter
|
||||||
|
* This class defines a generic memory cache management system
|
||||||
|
* to limit memory usage to a fixed global maximum.
|
||||||
|
*
|
||||||
|
* Please use the C-API in MEM_CacheLimiterC-Api.h for code written in C.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* class BigFatImage {
|
||||||
|
* public:
|
||||||
|
* ~BigFatImage() { tell_everyone_we_are_gone(this); }
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* void doit() {
|
||||||
|
* MEM_Cache<BigFatImage> BigFatImages;
|
||||||
|
*
|
||||||
|
* MEM_Cache_Handle<BigFatImage>* h = BigFatImages.insert(new BigFatImage);
|
||||||
|
*
|
||||||
|
* BigFatImages.enforce_limits();
|
||||||
|
* h->ref();
|
||||||
|
*
|
||||||
|
* work with image...
|
||||||
|
*
|
||||||
|
* h->unref();
|
||||||
|
*
|
||||||
|
* leave image in cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include "MEM_Allocator.h"
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class MEM_CacheLimiter;
|
||||||
|
|
||||||
|
#ifndef __MEM_cache_limiter_c_api_h_included__
|
||||||
|
extern "C" {
|
||||||
|
extern void MEM_CacheLimiter_set_maximum(int m);
|
||||||
|
extern int MEM_CacheLimiter_get_maximum();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class MEM_CacheLimiterHandle {
|
||||||
|
public:
|
||||||
|
explicit MEM_CacheLimiterHandle(T * data_,
|
||||||
|
MEM_CacheLimiter<T> * parent_)
|
||||||
|
: data(data_), refcount(0), parent(parent_) { }
|
||||||
|
|
||||||
|
void ref() {
|
||||||
|
refcount++;
|
||||||
|
}
|
||||||
|
void unref() {
|
||||||
|
refcount--;
|
||||||
|
}
|
||||||
|
T * get() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
const T * get() const {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
int get_refcount() const {
|
||||||
|
return refcount;
|
||||||
|
}
|
||||||
|
bool can_destroy() const {
|
||||||
|
return !data || !refcount;
|
||||||
|
}
|
||||||
|
bool destroy_if_possible() {
|
||||||
|
if (can_destroy()) {
|
||||||
|
delete data;
|
||||||
|
data = 0;
|
||||||
|
unmanage();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void unmanage() {
|
||||||
|
parent->unmanage(this);
|
||||||
|
}
|
||||||
|
void touch() {
|
||||||
|
parent->touch(this);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
friend class MEM_CacheLimiter<T>;
|
||||||
|
|
||||||
|
T * data;
|
||||||
|
int refcount;
|
||||||
|
typename std::list<MEM_CacheLimiterHandle<T> *,
|
||||||
|
MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator me;
|
||||||
|
MEM_CacheLimiter<T> * parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class MEM_CacheLimiter {
|
||||||
|
public:
|
||||||
|
typedef typename std::list<MEM_CacheLimiterHandle<T> *,
|
||||||
|
MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator iterator;
|
||||||
|
~MEM_CacheLimiter() {
|
||||||
|
for (iterator it = queue.begin(); it != queue.end(); it++) {
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MEM_CacheLimiterHandle<T> * insert(T * elem) {
|
||||||
|
queue.push_back(new MEM_CacheLimiterHandle<T>(elem, this));
|
||||||
|
iterator it = queue.end();
|
||||||
|
--it;
|
||||||
|
queue.back()->me = it;
|
||||||
|
return queue.back();
|
||||||
|
}
|
||||||
|
void unmanage(MEM_CacheLimiterHandle<T> * handle) {
|
||||||
|
queue.erase(handle->me);
|
||||||
|
delete handle;
|
||||||
|
}
|
||||||
|
void enforce_limits() {
|
||||||
|
// this is rather _ugly_!
|
||||||
|
extern int mem_in_use;
|
||||||
|
|
||||||
|
int max = MEM_CacheLimiter_get_maximum();
|
||||||
|
if (max == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (iterator it = queue.begin();
|
||||||
|
it != queue.end() && mem_in_use > max;) {
|
||||||
|
iterator jt = it;
|
||||||
|
++it;
|
||||||
|
(*jt)->destroy_if_possible();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void touch(MEM_CacheLimiterHandle<T> * handle) {
|
||||||
|
queue.push_back(handle);
|
||||||
|
queue.erase(handle->me);
|
||||||
|
iterator it = queue.end();
|
||||||
|
--it;
|
||||||
|
handle->me = it;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::list<MEM_CacheLimiterHandle<T>*,
|
||||||
|
MEM_Allocator<MEM_CacheLimiterHandle<T> *> > queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
141
intern/memutil/MEM_CacheLimiterC-Api.h
Normal file
141
intern/memutil/MEM_CacheLimiterC-Api.h
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contributor(s): Peter Schlaile <peter@schlaile.de> 2005
|
||||||
|
*
|
||||||
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MEM_cache_limiter_c_api_h_included__
|
||||||
|
#define __MEM_cache_limiter_c_api_h_included__ 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct MEM_CacheLimiter_s;
|
||||||
|
struct MEM_CacheLimiterHandle_s;
|
||||||
|
|
||||||
|
typedef struct MEM_CacheLimiter_s MEM_CacheLimiterC;
|
||||||
|
typedef struct MEM_CacheLimiterHandle_s MEM_CacheLimiterHandleC;
|
||||||
|
|
||||||
|
#ifndef __MEM_cache_limiter_h_included__
|
||||||
|
extern void MEM_CacheLimiter_set_maximum(int m);
|
||||||
|
extern int MEM_CacheLimiter_get_maximum();
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* Create new MEM_CacheLimiter object
|
||||||
|
* managed objects are destructed with the data_destructor
|
||||||
|
*
|
||||||
|
* @param data_destructor
|
||||||
|
* @return A new MEM_CacheLimter object
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern MEM_CacheLimiterC * new_MEM_CacheLimiter(
|
||||||
|
void (*data_destructor) (void * data));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete MEM_CacheLimiter
|
||||||
|
*
|
||||||
|
* Frees the memory of the CacheLimiter but does not touch managed objects!
|
||||||
|
*
|
||||||
|
* @param This "This" pointer
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage object
|
||||||
|
*
|
||||||
|
* @param This "This" pointer, data data object to manage
|
||||||
|
* @return CacheLimiterHandle to ref, unref, touch the managed object
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern MEM_CacheLimiterHandleC * MEM_CacheLimiter_insert(
|
||||||
|
MEM_CacheLimiterC * This, void * data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free objects until memory constraints are satisfied
|
||||||
|
*
|
||||||
|
* @param This "This" pointer
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC * This);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmanage object previously inserted object.
|
||||||
|
* Does _not_ delete managed object!
|
||||||
|
*
|
||||||
|
* @param This "This" pointer, handle of object
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC * handle);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raise priority of object (put it at the tail of the deletion chain)
|
||||||
|
*
|
||||||
|
* @param handle of object
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC * handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment reference counter. Objects with reference counter != 0 are _not_
|
||||||
|
* deleted.
|
||||||
|
*
|
||||||
|
* @param handle of object
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC * handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement reference counter. Objects with reference counter != 0 are _not_
|
||||||
|
* deleted.
|
||||||
|
*
|
||||||
|
* @param handle of object
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC * handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get reference counter.
|
||||||
|
*
|
||||||
|
* @param This "This" pointer, handle of object
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC * handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get pointer to managed object
|
||||||
|
*
|
||||||
|
* @param handle of object
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC * handle);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@@ -3,6 +3,6 @@ Import ('env')
|
|||||||
|
|
||||||
sources = env.Glob('intern/*.cpp')
|
sources = env.Glob('intern/*.cpp')
|
||||||
|
|
||||||
incs = '.'
|
incs = '. ..'
|
||||||
|
|
||||||
env.BlenderLib ('blender_MEM', sources, Split(incs), [], libtype='intern', priority = 10 )
|
env.BlenderLib ('blender_MEM', sources, Split(incs), [], libtype='intern', priority = 10 )
|
||||||
|
195
intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
Normal file
195
intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
/**
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contributor(s): Peter Schlaile <peter@schlaile.de> 2005
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "MEM_CacheLimiter.h"
|
||||||
|
#include "MEM_CacheLimiterC-Api.h"
|
||||||
|
|
||||||
|
static int & get_max()
|
||||||
|
{
|
||||||
|
static int m = 32*1024*1024;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_CacheLimiter_set_maximum(int m)
|
||||||
|
{
|
||||||
|
get_max() = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MEM_CacheLimiter_get_maximum()
|
||||||
|
{
|
||||||
|
return get_max();
|
||||||
|
}
|
||||||
|
|
||||||
|
class MEM_CacheLimiterHandleCClass;
|
||||||
|
class MEM_CacheLimiterCClass;
|
||||||
|
|
||||||
|
typedef MEM_CacheLimiterHandle<MEM_CacheLimiterHandleCClass> handle_t;
|
||||||
|
typedef MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache_t;
|
||||||
|
typedef std::list<MEM_CacheLimiterHandleCClass*,
|
||||||
|
MEM_Allocator<MEM_CacheLimiterHandleCClass* > > list_t;
|
||||||
|
|
||||||
|
class MEM_CacheLimiterCClass {
|
||||||
|
public:
|
||||||
|
MEM_CacheLimiterCClass(void (*data_destructor_) (void * data))
|
||||||
|
: data_destructor(data_destructor_) {
|
||||||
|
}
|
||||||
|
~MEM_CacheLimiterCClass();
|
||||||
|
|
||||||
|
handle_t * insert(void * data);
|
||||||
|
|
||||||
|
void destruct(void * data,
|
||||||
|
list_t::iterator it);
|
||||||
|
|
||||||
|
cache_t * get_cache() {
|
||||||
|
return &cache;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void (*data_destructor) (void * data);
|
||||||
|
|
||||||
|
MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache;
|
||||||
|
|
||||||
|
list_t cclass_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MEM_CacheLimiterHandleCClass {
|
||||||
|
public:
|
||||||
|
MEM_CacheLimiterHandleCClass(void * data_,
|
||||||
|
MEM_CacheLimiterCClass * parent_)
|
||||||
|
: data(data_), parent(parent_) { }
|
||||||
|
~MEM_CacheLimiterHandleCClass();
|
||||||
|
void set_iter(list_t::iterator it_) {
|
||||||
|
it = it_;
|
||||||
|
}
|
||||||
|
void set_data(void * data_) {
|
||||||
|
data = data_;
|
||||||
|
}
|
||||||
|
void * get_data() const {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void * data;
|
||||||
|
MEM_CacheLimiterCClass * parent;
|
||||||
|
list_t::iterator it;
|
||||||
|
};
|
||||||
|
|
||||||
|
handle_t * MEM_CacheLimiterCClass::insert(void * data)
|
||||||
|
{
|
||||||
|
cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this));
|
||||||
|
list_t::iterator it = cclass_list.end();
|
||||||
|
--it;
|
||||||
|
cclass_list.back()->set_iter(it);
|
||||||
|
|
||||||
|
return cache.insert(cclass_list.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_CacheLimiterCClass::destruct(void * data, list_t::iterator it)
|
||||||
|
{
|
||||||
|
data_destructor(data);
|
||||||
|
cclass_list.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_CacheLimiterHandleCClass::~MEM_CacheLimiterHandleCClass()
|
||||||
|
{
|
||||||
|
if (data) {
|
||||||
|
parent->destruct(data, it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass()
|
||||||
|
{
|
||||||
|
// should not happen, but don't leak memory in this case...
|
||||||
|
for (list_t::iterator it = cclass_list.begin();
|
||||||
|
it != cclass_list.end(); it++) {
|
||||||
|
(*it)->set_data(0);
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
static inline MEM_CacheLimiterCClass* cast(MEM_CacheLimiterC * l)
|
||||||
|
{
|
||||||
|
return (MEM_CacheLimiterCClass*) l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline handle_t* cast(MEM_CacheLimiterHandleC * l)
|
||||||
|
{
|
||||||
|
return (handle_t*) l;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_CacheLimiterC * new_MEM_CacheLimiter(
|
||||||
|
void (*data_destructor) (void * data))
|
||||||
|
{
|
||||||
|
return (MEM_CacheLimiterC*) new MEM_CacheLimiterCClass(
|
||||||
|
data_destructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This)
|
||||||
|
{
|
||||||
|
delete cast(This);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_CacheLimiterHandleC * MEM_CacheLimiter_insert(
|
||||||
|
MEM_CacheLimiterC * This, void * data)
|
||||||
|
{
|
||||||
|
return (MEM_CacheLimiterHandleC *) cast(This)->insert(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC * This)
|
||||||
|
{
|
||||||
|
cast(This)->get_cache()->enforce_limits();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC * handle)
|
||||||
|
{
|
||||||
|
cast(handle)->unmanage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC * handle)
|
||||||
|
{
|
||||||
|
cast(handle)->touch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC * handle)
|
||||||
|
{
|
||||||
|
cast(handle)->ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC * handle)
|
||||||
|
{
|
||||||
|
cast(handle)->unref();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC * handle)
|
||||||
|
{
|
||||||
|
return cast(handle)->get_refcount();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC * handle)
|
||||||
|
{
|
||||||
|
return cast(handle)->get()->get_data();
|
||||||
|
}
|
@@ -38,5 +38,5 @@ include nan_compile.mk
|
|||||||
|
|
||||||
CCFLAGS += $(LEVEL_2_CPP_WARNINGS)
|
CCFLAGS += $(LEVEL_2_CPP_WARNINGS)
|
||||||
|
|
||||||
CPPFLAGS += -I..
|
CPPFLAGS += -I.. -I../..
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user