Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
pixelpipe_cache.h File Reference

Pixelpipe cache for storing intermediate results in the pixelpipe. More...

#include <inttypes.h>
+ Include dependency graph for pixelpipe_cache.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  dt_dev_pixelpipe_cache_t
 

Typedefs

typedef struct dt_dev_pixelpipe_cache_t dt_dev_pixelpipe_cache_t
 

Functions

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)
 
struct 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.
 
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. 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.
 
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.
 
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.
 
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.
 
void dt_dev_pixelpipe_cache_print (dt_dev_pixelpipe_cache_t *cache)
 
int dt_dev_pixel_pipe_cache_remove_lru (dt_dev_pixelpipe_cache_t *cache)
 
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.
 
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.
 
struct 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_wrlock_entry (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, gboolean lock, struct dt_pixel_cache_entry_t *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, struct dt_pixel_cache_entry_t *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, 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.
 
void dt_dev_pixelpipe_cache_auto_destroy_apply (dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, const int id, struct dt_pixel_cache_entry_t *entry)
 Free the entry matching hash if it has the flag "auto_destroy" and its pipe id matches. See dt_dev_pixelpipe_cache_flag_auto_destroy(). This will not check reference count nor read/write locks, so it has to happen in the thread that created the entry, flagged it and owns it. Ensure your hashes are truly unique and not shared between pipelines to ensure another thread will not free this or that another thread ends up using it.
 

Detailed Description

Pixelpipe cache for storing intermediate results in the pixelpipe.

This cache can be used locally (in the pixelpipe) or globally (in the whole app). Current implementation is global, using darktable.pipeline_threadsafe mutex lock to protect cache entries addition/removal accross threads. The mutex lock protects the whole recursive pixelpipe, so no internal locking is needed nor implemented here.

Typedef Documentation

◆ dt_dev_pixelpipe_cache_t

Function Documentation

◆ 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_auto_destroy_apply()

void dt_dev_pixelpipe_cache_auto_destroy_apply ( dt_dev_pixelpipe_cache_t cache,
const uint64_t  hash,
const int  id,
struct dt_pixel_cache_entry_t entry 
)

Free the entry matching hash if it has the flag "auto_destroy" and its pipe id matches. See dt_dev_pixelpipe_cache_flag_auto_destroy(). This will not check reference count nor read/write locks, so it has to happen in the thread that created the entry, flagged it and owns it. Ensure your hashes are truly unique and not shared between pipelines to ensure another thread will not free this or that another thread ends up using it.

Parameters
cache
hash

◆ 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_process_image_job(), dt_dev_process_preview_job(), 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. 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
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_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()

struct 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.

◆ dt_dev_pixelpipe_cache_get_entry_from_data()

struct 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_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 
)

◆ 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 
)