![]() |
Ansel 0.0
A darktable fork - bloat + design vision
|
Pixelpipe cache for storing intermediate results in the pixelpipe. More...
#include <inttypes.h>
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_t * | dt_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_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. | |
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_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. | |
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. | |
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 struct dt_dev_pixelpipe_cache_t dt_dev_pixelpipe_cache_t |
int dt_dev_pixel_pipe_cache_remove_lru | ( | dt_dev_pixelpipe_cache_t * | cache | ) |
remove the least used cache entry
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().
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.
cache | |
hash |
void dt_dev_pixelpipe_cache_cleanup | ( | dt_dev_pixelpipe_cache_t * | cache | ) |
References dt_pthread_mutex_destroy(), dt_dev_pixelpipe_cache_t::entries, and dt_dev_pixelpipe_cache_t::lock.
Referenced by dt_cleanup().
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.
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().
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.
cache | |
id | ID 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().
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.
cache | |
hash | State checksum of the cache line. |
size | Buffer size in bytes. |
name | Name of the cache line (for debugging). |
id | ID of the pipeline owning the cache line. |
data | Pointer to the buffer pointer (returned). |
dsc | Pointer to the buffer descriptor (returned). |
cache_entry | a reference to the cache entry, to be reused later. Can be NULL. The caller doesn't own the data and shouldn't free it. |
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().
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.
cache | |
hash |
References _non_threadsafe_cache_get_entry(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), and dt_dev_pixelpipe_cache_t::lock.
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.
cache | |
data |
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().
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.
cache | |
hash | |
data | |
dsc |
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().
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.
cache | |
data | |
cache_entry | a reference to the cache entry, to be reused later. Can be NULL. The caller doesn't own the data and shouldn't free it. |
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_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.
[out] | returns | 0 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().
void dt_dev_pixelpipe_cache_print | ( | dt_dev_pixelpipe_cache_t * | cache | ) |
print out cache lines/hashes (debug).
References dt_dev_pixelpipe_cache_t::current_memory, darktable, DT_DEBUG_PIPE, dt_print(), dt_dev_pixelpipe_cache_t::entries, dt_dev_pixelpipe_cache_t::hits, dt_dev_pixelpipe_cache_t::max_memory, dt_dev_pixelpipe_cache_t::queries, and darktable_t::unmuted.
Referenced by dt_dev_pixelpipe_process().
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.
cache | |
hash | |
lock | TRUE to lock, FALSE to release |
References _non_threadsafe_cache_get_entry(), dt_pixel_cache_message(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pthread_rwlock_rdlock, dt_pthread_rwlock_unlock, dt_pixel_cache_entry_t::lock, dt_dev_pixelpipe_cache_t::lock, and TRUE.
Referenced by _update_gui_backbuf(), dt_dev_pixelpipe_process_rec(), and dt_imageio_export_with_flags().
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.
cache | |
hash | |
lock | TRUE 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().
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.
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().
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.
cache | |
hash | |
lock | TRUE to lock, FALSE to release |
References _non_threadsafe_cache_get_entry(), dt_pixel_cache_message(), dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), dt_pthread_rwlock_unlock, dt_pthread_rwlock_wrlock, dt_pixel_cache_entry_t::lock, dt_dev_pixelpipe_cache_t::lock, and TRUE.
Referenced by _init_base_buffer(), _sample_all(), and dt_dev_pixelpipe_process_rec().