Files
test2/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
Campbell Barton c434782e3a File headers: SPDX License migration
Use a shorter/simpler license convention, stops the header taking so
much space.

Follow the SPDX license specification: https://spdx.org/licenses

- C/C++/objc/objc++
- Python
- Shell Scripts
- CMake, GNUmakefile

While most of the source tree has been included

- `./extern/` was left out.
- `./intern/cycles` & `./intern/atomic` are also excluded because they
  use different header conventions.

doc/license/SPDX-license-identifiers.txt has been added to list SPDX all
used identifiers.

See P2788 for the script that automated these edits.

Reviewed By: brecht, mont29, sergey

Ref D14069
2022-02-11 09:14:36 +11:00

216 lines
4.6 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_memutil
*/
#include <cstddef>
#include "MEM_CacheLimiter.h"
#include "MEM_CacheLimiterC-Api.h"
static bool is_disabled = false;
static size_t &get_max()
{
static size_t m = 32 * 1024 * 1024;
return m;
}
void MEM_CacheLimiter_set_maximum(size_t m)
{
get_max() = m;
}
size_t MEM_CacheLimiter_get_maximum()
{
return get_max();
}
void MEM_CacheLimiter_set_disabled(bool disabled)
{
is_disabled = disabled;
}
bool MEM_CacheLimiter_is_disabled(void)
{
return is_disabled;
}
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(MEM_CacheLimiter_Destruct_Func data_destructor_,
MEM_CacheLimiter_DataSize_Func data_size)
: data_destructor(data_destructor_), cache(data_size)
{
}
~MEM_CacheLimiterCClass();
handle_t *insert(void *data);
void destruct(void *data, list_t::iterator it);
cache_t *get_cache()
{
return &cache;
}
private:
MEM_CacheLimiter_Destruct_Func data_destructor;
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(NULL);
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(MEM_CacheLimiter_Destruct_Func data_destructor,
MEM_CacheLimiter_DataSize_Func data_size)
{
return (MEM_CacheLimiterC *)new MEM_CacheLimiterCClass(data_destructor, data_size);
}
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();
}
void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
MEM_CacheLimiter_ItemPriority_Func item_priority_func)
{
cast(This)->get_cache()->set_item_priority_func(item_priority_func);
}
void MEM_CacheLimiter_ItemDestroyable_Func_set(
MEM_CacheLimiterC *This, MEM_CacheLimiter_ItemDestroyable_Func item_destroyable_func)
{
cast(This)->get_cache()->set_item_destroyable_func(item_destroyable_func);
}
size_t MEM_CacheLimiter_get_memory_in_use(MEM_CacheLimiterC *This)
{
return cast(This)->get_cache()->get_memory_in_use();
}