Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
pixelpipe_cache.c File Reference
#include "develop/pixelpipe_cache.h"
#include "common/darktable.h"
#include "common/debug.h"
#include "develop/format.h"
#include "develop/pixelpipe_hb.h"
#include <glib.h>
#include <stdlib.h>
+ Include dependency graph for pixelpipe_cache.c:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  dt_pixel_cache_entry_t
 
struct  _cache_lru_t
 
struct  _cache_invalidate_t
 

Typedefs

typedef struct dt_pixel_cache_entry_t dt_pixel_cache_entry_t
 
typedef struct _cache_lru_t _cache_lru_t
 
typedef struct _cache_invalidate_t _cache_invalidate_t
 

Functions

void _non_thread_safe_cache_ref_count_entry (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
 
dt_pixel_cache_entry_t_non_threadsafe_cache_get_entry (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash)
 
dt_pixel_cache_entry_tdt_dev_pixelpipe_cache_get_entry (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash)
 Get an internal reference to the cache entry matching hash. If you are going to access this entry more than once, keeping the reference and using it instead of hashes will prevent redundant lookups.
 
size_t dt_pixel_cache_get_size (dt_pixel_cache_entry_t *cache_entry)
 
void dt_pixel_cache_message (dt_pixel_cache_entry_t *cache_entry, const char *message, gboolean verbose)
 
int _non_thread_safe_cache_remove (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const gboolean force, dt_pixel_cache_entry_t *cache_entry)
 
int dt_dev_pixelpipe_cache_remove (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const gboolean force, dt_pixel_cache_entry_t *cache_entry)
 Arbitrarily remove the cache entry matching hash. Entries having a reference count > 0 (inter-thread locked) or being having their read/write lock locked will be ignored. If force is TRUE, we ignore reference count, but not locks.
 
void _cache_get_oldest (gpointer key, gpointer value, gpointer user_data)
 
static int _non_thread_safe_pixel_pipe_cache_remove_lru (dt_dev_pixelpipe_cache_t *cache)
 
int dt_dev_pixel_pipe_cache_remove_lru (dt_dev_pixelpipe_cache_t *cache)
 
static dt_pixel_cache_entry_tdt_pixel_cache_new_entry (const uint64_t hash, const size_t size, const dt_iop_buffer_dsc_t dsc, const char *name, const int id, dt_dev_pixelpipe_cache_t *cache)
 
static void _free_cache_entry (dt_pixel_cache_entry_t *cache_entry)
 
dt_dev_pixelpipe_cache_tdt_dev_pixelpipe_cache_init (size_t max_memory)
 
void dt_dev_pixelpipe_cache_cleanup (dt_dev_pixelpipe_cache_t *cache)
 
int dt_dev_pixelpipe_cache_get (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const size_t size, const char *name, const int id, void **data, dt_iop_buffer_dsc_t **dsc, dt_pixel_cache_entry_t **entry)
 Get a cache line from the cache.
 
int dt_dev_pixelpipe_cache_get_existing (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, void **data, dt_iop_buffer_dsc_t **dsc, dt_pixel_cache_entry_t **entry)
 Get an existing cache line from the cache. This is similar to dt_dev_pixelpipe_cache_get, but it does not create a new cache line if it is not found.
 
gboolean _for_each_remove (gpointer key, gpointer value, gpointer user_data)
 
void dt_dev_pixelpipe_cache_flush (dt_dev_pixelpipe_cache_t *cache, const int id)
 Remove cache lines matching id. Entries locked in read/write or having reference count greater than 0 are not removed.
 
uint64_t _non_thread_safe_cache_get_hash_data (dt_dev_pixelpipe_cache_t *cache, void *data, dt_pixel_cache_entry_t **entry)
 
uint64_t dt_dev_pixelpipe_cache_get_hash_data (dt_dev_pixelpipe_cache_t *cache, void *data, dt_pixel_cache_entry_t **entry)
 Find the hash of the cache entry holding the buffer data.
 
dt_pixel_cache_entry_tdt_dev_pixelpipe_cache_get_entry_from_data (dt_dev_pixelpipe_cache_t *cache, void *data)
 Return a reference to the cache entry holding the data buffer, or NULL if not found.
 
void dt_dev_pixelpipe_cache_ref_count_entry (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
 Increase/Decrease the reference count on the cache line as to prevent LRU item removal. This function should be called within a read/write lock-protected section to avoid changing an entry while or after it is deleted in parallel.
 
void dt_dev_pixelpipe_cache_wrlock_entry (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
 Lock or release the write lock on the entry.
 
void dt_dev_pixelpipe_cache_rdlock_entry (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
 Lock or release the read lock on the entry.
 
void dt_dev_pixelpipe_cache_flag_auto_destroy (dt_dev_pixelpipe_cache_t *cache, uint64_t hash, dt_pixel_cache_entry_t *cache_entry)
 Flag the cache entry matching hash as "auto_destroy". This is useful for short-lived/disposable cache entries, that won't be needed in the future. These will be freed out of the typical LRU, aged-based garbage collection. The thread that tagged this entry as "auto_destroy" is responsible for freeing it as soon as it is done with it, using dt_dev_pixelpipe_cache_auto_destroy_apply(). If not manually freed this way, the entry will be caught using the generic LRU garbage collection.
 
void dt_dev_pixel_pipe_cache_auto_destroy_apply (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const int id, dt_pixel_cache_entry_t *cache_entry)
 
void dt_dev_pixelpipe_cache_print (dt_dev_pixelpipe_cache_t *cache)
 

Typedef Documentation

◆ _cache_invalidate_t

◆ _cache_lru_t

typedef struct _cache_lru_t _cache_lru_t

◆ dt_pixel_cache_entry_t

Function Documentation

◆ _cache_get_oldest()

◆ _for_each_remove()

gboolean _for_each_remove ( gpointer  key,
gpointer  value,
gpointer  user_data 
)

◆ _free_cache_entry()

◆ _non_thread_safe_cache_get_hash_data()

◆ _non_thread_safe_cache_ref_count_entry()

◆ _non_thread_safe_cache_remove()

◆ _non_thread_safe_pixel_pipe_cache_remove_lru()

◆ _non_threadsafe_cache_get_entry()

◆ dt_dev_pixel_pipe_cache_auto_destroy_apply()

◆ dt_dev_pixel_pipe_cache_remove_lru()

int dt_dev_pixel_pipe_cache_remove_lru ( dt_dev_pixelpipe_cache_t cache)

remove the least used cache entry

Returns
0 on success, 1 on error

References _non_thread_safe_pixel_pipe_cache_remove_lru(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), error(), and dt_dev_pixelpipe_cache_t::lock.

Referenced by dt_alloc_align().

◆ dt_dev_pixelpipe_cache_cleanup()

◆ dt_dev_pixelpipe_cache_flag_auto_destroy()

void dt_dev_pixelpipe_cache_flag_auto_destroy ( dt_dev_pixelpipe_cache_t cache,
uint64_t  hash,
struct dt_pixel_cache_entry_t entry 
)

Flag the cache entry matching hash as "auto_destroy". This is useful for short-lived/disposable cache entries, that won't be needed in the future. These will be freed out of the typical LRU, aged-based garbage collection. The thread that tagged this entry as "auto_destroy" is responsible for freeing it as soon as it is done with it, using dt_dev_pixelpipe_cache_auto_destroy_apply(). If not manually freed this way, the entry will be caught using the generic LRU garbage collection.

Parameters
cache
hash

References _non_threadsafe_cache_get_entry(), dt_pixel_cache_entry_t::auto_destroy, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::lock, and TRUE.

Referenced by dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_flush()

void dt_dev_pixelpipe_cache_flush ( dt_dev_pixelpipe_cache_t cache,
const int  id 
)

Remove cache lines matching id. Entries locked in read/write or having reference count greater than 0 are not removed.

Parameters
cache
idID of the pipeline owning the cache line, or -1 to remove all lines.

References _for_each_remove(), dt_dev_pixelpipe_cache_t::current_memory, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_dev_pixelpipe_cache_t::entries, and dt_dev_pixelpipe_cache_t::lock.

Referenced by dt_dev_darkroom_pipeline(), and dt_dev_reprocess_all().

◆ dt_dev_pixelpipe_cache_get()

int dt_dev_pixelpipe_cache_get ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
const size_t  size,
const char *  name,
const int  id,
void **  data,
struct dt_iop_buffer_dsc_t **  dsc,
struct dt_pixel_cache_entry_t **  entry 
)

Get a cache line from the cache.

WARNING: This internally increases the reference count, so you have to manually decrease it using dt_dev_pixelpipe_ref_count_entry() once the cache line content has been consumed or it will never be freed.

WARNING: if the cache line was newly allocated, a write lock is put on straight away. You will have to release it from the same calling thread next, to avoid dead locks.

Parameters
cache
hashState checksum of the cache line.
sizeBuffer size in bytes.
nameName of the cache line (for debugging).
idID of the pipeline owning the cache line.
dataPointer to the buffer pointer (returned).
dscPointer to the buffer descriptor (returned).
cache_entrya reference to the cache entry, to be reused later. Can be NULL. The caller doesn't own the data and shouldn't free it.
Returns
int 1 if the cache line was freshly allocated, 0 if it was found in the cache.

References _non_thread_safe_cache_ref_count_entry(), _non_threadsafe_cache_get_entry(), dt_pixel_cache_entry_t::age, darktable, dt_pixel_cache_entry_t::data, dt_pixel_cache_entry_t::dsc, DT_DEBUG_PIPE, dt_dev_pixelpipe_cache_rdlock_entry(), dt_dev_pixelpipe_cache_wrlock_entry(), dt_pixel_cache_message(), dt_pixel_cache_new_entry(), dt_print(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, dt_dev_pixelpipe_cache_t::hits, dt_dev_pixelpipe_cache_t::lock, name, darktable_t::pixelpipe_cache, dt_dev_pixelpipe_cache_t::queries, size, and TRUE.

Referenced by _init_base_buffer(), and dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_get_entry()

dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_get_entry ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash 
)

Get an internal reference to the cache entry matching hash. If you are going to access this entry more than once, keeping the reference and using it instead of hashes will prevent redundant lookups.

Parameters
cache
hash
Returns
struct dt_pixel_cache_entry_t*

References _non_threadsafe_cache_get_entry(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), and dt_dev_pixelpipe_cache_t::lock.

Referenced by dt_dev_pixelpipe_cache_rdlock_entry(), and dt_dev_pixelpipe_cache_wrlock_entry().

◆ dt_dev_pixelpipe_cache_get_entry_from_data()

dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_get_entry_from_data ( dt_dev_pixelpipe_cache_t cache,
void data 
)

Return a reference to the cache entry holding the data buffer, or NULL if not found.

WARNING: this immediately puts a read lock on the entry cache, if found. You will need to manually release it later with dt_dev_pixelpipe_cache_rdlock_entry() or you will get a deadlock and this entry will never be deleted.

Parameters
cache
data
Returns
dt_pixel_cache_entry_t*

References _non_thread_safe_cache_get_hash_data(), dt_pixel_cache_message(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pthread_rwlock_rdlock, dt_pixel_cache_entry_t::lock, dt_dev_pixelpipe_cache_t::lock, and TRUE.

Referenced by _update_gui_backbuf(), and dt_imageio_export_with_flags().

◆ dt_dev_pixelpipe_cache_get_existing()

int dt_dev_pixelpipe_cache_get_existing ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
void **  data,
struct dt_iop_buffer_dsc_t **  dsc,
struct dt_pixel_cache_entry_t **  entry 
)

Get an existing cache line from the cache. This is similar to dt_dev_pixelpipe_cache_get, but it does not create a new cache line if it is not found.

This internally increases the reference count, so you have to manually decrease it using dt_dev_pixelpipe_ref_count_entry() once the cache line content has been consumed or it will never be freed.

Parameters
cache
hash
data
dsc
Returns
int TRUE if found, FALSE if not found.

References _non_thread_safe_cache_ref_count_entry(), _non_threadsafe_cache_get_entry(), dt_pixel_cache_entry_t::age, darktable, dt_pixel_cache_entry_t::data, dt_pixel_cache_entry_t::dsc, dt_dev_pixelpipe_cache_rdlock_entry(), dt_pixel_cache_message(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, dt_dev_pixelpipe_cache_t::hits, dt_dev_pixelpipe_cache_t::lock, darktable_t::pixelpipe_cache, dt_dev_pixelpipe_cache_t::queries, and TRUE.

Referenced by dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_get_hash_data()

uint64_t dt_dev_pixelpipe_cache_get_hash_data ( dt_dev_pixelpipe_cache_t cache,
void data,
struct dt_pixel_cache_entry_t **  entry 
)

Find the hash of the cache entry holding the buffer data.

Parameters
cache
data
cache_entrya reference to the cache entry, to be reused later. Can be NULL. The caller doesn't own the data and shouldn't free it.
Returns
uint64_t defaults to 0 if nothing was found.

References _non_thread_safe_cache_get_hash_data(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), and dt_dev_pixelpipe_cache_t::lock.

Referenced by dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_init()

dt_dev_pixelpipe_cache_t * dt_dev_pixelpipe_cache_init ( size_t  max_memory)

constructs a new cache with given cache line count (entries) and float buffer entry size in bytes.

Parameters
[out]returns0 if fail to allocate mem cache.

References _free_cache_entry(), dt_dev_pixelpipe_cache_t::current_memory, dt_pthread_mutex_init(), dt_dev_pixelpipe_cache_t::entries, dt_dev_pixelpipe_cache_t::hits, dt_dev_pixelpipe_cache_t::lock, dt_dev_pixelpipe_cache_t::max_memory, and dt_dev_pixelpipe_cache_t::queries.

Referenced by dt_init().

◆ dt_dev_pixelpipe_cache_print()

◆ dt_dev_pixelpipe_cache_rdlock_entry()

void dt_dev_pixelpipe_cache_rdlock_entry ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
gboolean  lock,
struct dt_pixel_cache_entry_t entry 
)

Lock or release the read lock on the entry.

Parameters
cache
hashchecksum of the cache entry to fetch. Optional if entry is not NULL.
lockTRUE to lock, FALSE to release
entryThe cache entry object to lock, if a reference is already known. Can be NULL, but then you need to pass a hash.

References dt_dev_pixelpipe_cache_get_entry(), dt_pixel_cache_message(), dt_pthread_rwlock_rdlock, dt_pthread_rwlock_unlock, dt_pixel_cache_entry_t::lock, and TRUE.

Referenced by _update_gui_backbuf(), dt_dev_pixelpipe_cache_get(), dt_dev_pixelpipe_cache_get_existing(), dt_dev_pixelpipe_process_rec(), dt_imageio_export_with_flags(), and pixelpipe_process_on_CPU().

◆ dt_dev_pixelpipe_cache_ref_count_entry()

void dt_dev_pixelpipe_cache_ref_count_entry ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
gboolean  lock,
struct dt_pixel_cache_entry_t entry 
)

Increase/Decrease the reference count on the cache line as to prevent LRU item removal. This function should be called within a read/write lock-protected section to avoid changing an entry while or after it is deleted in parallel.

WARNING: cache entries whose reference count is greater than 0 will never be deleted from cache.

Parameters
cache
hash
lockTRUE to lock, FALSE to unlock

References _non_thread_safe_cache_ref_count_entry(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), and dt_dev_pixelpipe_cache_t::lock.

Referenced by _update_gui_backbuf(), dt_dev_pixelpipe_process_rec(), and dt_imageio_export_with_flags().

◆ dt_dev_pixelpipe_cache_remove()

int dt_dev_pixelpipe_cache_remove ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
const gboolean  force,
struct dt_pixel_cache_entry_t entry 
)

Arbitrarily remove the cache entry matching hash. Entries having a reference count > 0 (inter-thread locked) or being having their read/write lock locked will be ignored. If force is TRUE, we ignore reference count, but not locks.

Parameters
cache
hash
force

References _non_thread_safe_cache_remove(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), error(), and dt_dev_pixelpipe_cache_t::lock.

Referenced by _update_gui_backbuf(), and dt_dev_pixelpipe_process_rec().

◆ dt_dev_pixelpipe_cache_wrlock_entry()

void dt_dev_pixelpipe_cache_wrlock_entry ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
gboolean  lock,
struct dt_pixel_cache_entry_t entry 
)

◆ dt_pixel_cache_get_size()

size_t dt_pixel_cache_get_size ( dt_pixel_cache_entry_t cache_entry)

◆ dt_pixel_cache_message()

◆ dt_pixel_cache_new_entry()