Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
caches/cache.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2011-2014 johannes hanika.
4 Copyright (C) 2012 Richard Wonka.
5 Copyright (C) 2012, 2014, 2016 Tobias Ellinghaus.
6 Copyright (C) 2013 Simon Spannagel.
7 Copyright (C) 2014-2016 Roman Lebedev.
8 Copyright (C) 2020 Pascal Obry.
9 Copyright (C) 2022 Martin Baƙinka.
10
11 darktable is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 darktable is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with darktable. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#ifndef DT_CACHES_CACHE_H
26#define DT_CACHES_CACHE_H
27
28#include "system/dtpthread.h"
29#include <glib.h>
30#include <inttypes.h>
31#include <stddef.h>
32
33typedef struct dt_cache_entry_t
34{
35 void *data;
36 size_t data_size;
37 size_t cost;
41 uint32_t key;
42}
44
45typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry));
46typedef void((*dt_cache_cleanup_t)(void *userdata, dt_cache_entry_t *entry));
47
62
65
66typedef struct dt_cache_t
67{
68 dt_pthread_mutex_t lock; // big fat lock. we're only expecting a couple hand full of cpu threads to use this concurrently.
69
70 size_t entry_size; // cache line allocation
71 size_t cost; // user supplied cost per cache line (bytes?)
72 size_t cost_quota; // quota to try and meet. but don't use as hard limit.
73
74 GHashTable *hashtable; // stores (key, entry) pairs
75 GList *lru; // last element is most recently used, first is about to be kicked from cache.
76
77 // callback functions for cache misses/garbage collection
78 dt_cache_allocate_t allocate;
79 dt_cache_allocate_t cleanup;
82}
84
85// entry size is only used if alloc callback is 0
86void dt_cache_init(dt_cache_t *cache, size_t entry_size, size_t cost_quota);
87void dt_cache_cleanup(dt_cache_t *cache);
88
89static inline void dt_cache_set_allocate_callback(dt_cache_t *cache, dt_cache_allocate_t allocate_cb,
90 void *allocate_data)
91{
92 cache->allocate = allocate_cb;
93 cache->allocate_data = allocate_data;
94}
96 void *cleanup_data)
97{
98 cache->cleanup = cleanup_cb;
99 cache->cleanup_data = cleanup_data;
100}
101
102// returns a slot in the cache for this key (newly allocated if need be), locked according to mode (r, w)
103#define dt_cache_get(A, B, C) dt_cache_get_with_caller(A, B, C, __FILE__, __LINE__)
104dt_cache_entry_t *dt_cache_get_with_caller(dt_cache_t *cache, const uint32_t key, char mode, const char *file, int line);
105// same but returns 0 if not allocated yet (both will block and wait for entry rw locks to be released)
106dt_cache_entry_t *dt_cache_testget(dt_cache_t *cache, const uint32_t key, char mode);
107// release a lock on a cache entry. the cache knows which one you mean (r or w).
108#define dt_cache_release(A, B) dt_cache_release_with_caller(A, B, __FILE__, __LINE__)
109void dt_cache_release_with_caller(dt_cache_t *cache, dt_cache_entry_t *entry, const char *file, int line);
110
111// 0: not contained
112int32_t dt_cache_contains(dt_cache_t *cache, const uint32_t key);
113// returns 0 on success, 1 if the key was not found.
114int32_t dt_cache_remove(dt_cache_t *cache, const uint32_t key);
115// seed a cache entry without running allocate callback. returns 0 on insert, 1 if already present, -1 on failure.
116int dt_cache_seed(dt_cache_t *cache, const uint32_t key, const void *data, size_t data_size, size_t cost,
117 gboolean aligned_alloc);
118// removes from the tip of the lru list, until the fill ratio of the hashtable
119// goes below the given parameter, in terms of the user defined cost measure.
120// will never lock and never fail, but sometimes not free memory (in case all
121// is locked)
122void dt_cache_gc(dt_cache_t *cache, const float fill_ratio);
123
124// iterate over all currently contained data blocks.
125// not thread safe! only use this for init/cleanup!
126// returns non zero the first time process() returns non zero.
128 int (*process)(const uint32_t key, const void *data, void *user_data),
129 void *user_data);
130
131#endif // DT_CACHES_CACHE_H
132
133// clang-format off
134// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
135// vim: shiftwidth=2 expandtab tabstop=2 cindent
136// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
137// clang-format on
__DT_CLONE_TARGETS__ int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
Definition ashift.c:3166
int32_t dt_cache_remove(dt_cache_t *cache, const uint32_t key)
int32_t dt_cache_contains(dt_cache_t *cache, const uint32_t key)
int dt_cache_seed(dt_cache_t *cache, const uint32_t key, const void *data, size_t data_size, size_t cost, gboolean aligned_alloc)
void dt_cache_entry_free_detached(dt_cache_entry_t *entry)
Release an entry from dt_cache_entry_new_detached(), and its data. NULL-safe.
static void dt_cache_set_cleanup_callback(dt_cache_t *cache, dt_cache_cleanup_t cleanup_cb, void *cleanup_data)
void dt_cache_gc(dt_cache_t *cache, const float fill_ratio)
void dt_cache_release_with_caller(dt_cache_t *cache, dt_cache_entry_t *entry, const char *file, int line)
dt_cache_entry_t * dt_cache_testget(dt_cache_t *cache, const uint32_t key, char mode)
dt_cache_entry_t * dt_cache_entry_new_detached(void)
Allocate a cache entry that belongs to NO cache, for a one-shot decode.
void dt_cache_init(dt_cache_t *cache, size_t entry_size, size_t cost_quota)
dt_cache_entry_t * dt_cache_get_with_caller(dt_cache_t *cache, const uint32_t key, char mode, const char *file, int line)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
static void dt_cache_set_allocate_callback(dt_cache_t *cache, dt_cache_allocate_t allocate_cb, void *allocate_data)
int dt_cache_for_all(dt_cache_t *cache, int(*process)(const uint32_t key, const void *data, void *user_data), void *user_data)
void dt_cache_cleanup(dt_cache_t *cache)
char * key
uint32_t key
GList * link
size_t data_size
dt_pthread_rwlock_t lock
int _lock_demoting
void * data
size_t cost
size_t cost
GList * lru
size_t cost_quota
void * allocate_data
GHashTable * hashtable
dt_cache_allocate_t allocate
dt_pthread_mutex_t lock
size_t entry_size
dt_cache_allocate_t cleanup
void * cleanup_data