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

The queue of consumers waiting for a pixel cacheline that does not exist yet. More...

#include <glib.h>
#include <stdint.h>
#include "system/dtpthread.h"
+ Include dependency graph for pixelpipe_cache_wait.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  dt_pixelpipe_cache_wait_t
 One consumer's outstanding request, owned by that consumer, not by the queue. More...
 

Typedefs

typedef void(* dt_pixelpipe_cache_ready_callback_t) (gpointer user_data)
 Called when the awaited cacheline finally exists. Runs on the caller's thread.
 
typedef struct dt_pixelpipe_cache_wait_t dt_pixelpipe_cache_wait_t
 One consumer's outstanding request, owned by that consumer, not by the queue.
 
typedef void(* dt_pixelpipe_cache_wait_visitor_t) (const dt_pixelpipe_cache_wait_t *wait, int64_t age_us, gpointer user_data)
 Walk the outstanding requests. callback is invoked under the queue lock, so it must not re-enter this module or the cache.
 

Functions

gboolean dt_pixelpipe_cache_wait_enqueue (dt_pixelpipe_cache_wait_t *wait)
 Queue wait, or refresh it in place if it is already queued for the same target.
 
GListdt_pixelpipe_cache_wait_take_matching (uint64_t hash, uint64_t producer_node_key, gboolean *drained)
 Take every waiter satisfied by a publication of hash from node producer_node_key.
 
gboolean dt_pixelpipe_cache_wait_cancel (dt_pixelpipe_cache_wait_t *wait, gboolean *drained)
 Remove wait from the queue if it is there, and reset it to an inert state.
 
guint dt_pixelpipe_cache_wait_pending_count (void)
 How many requests are outstanding. Diagnostics only.
 
void dt_pixelpipe_cache_wait_get_stats (uint64_t *queued, uint64_t *served, uint64_t *cancelled, uint64_t *immediate_hits, uint64_t *misses)
 Snapshot of the lifetime counters, for the dump. Any pointer may be NULL.
 
void dt_pixelpipe_cache_wait_count_immediate_hit (void)
 Count one cache hit that never needed to queue.
 
void dt_pixelpipe_cache_wait_count_miss (void)
 Count one miss that is about to queue.
 
void dt_pixelpipe_cache_wait_foreach_pending (dt_pixelpipe_cache_wait_visitor_t callback, gpointer user_data)
 

Detailed Description

The queue of consumers waiting for a pixel cacheline that does not exist yet.

A GUI consumer that asks the cache for an output the pipeline has not published yet – a histogram, a colour picker, the darkroom surface, autoset – leaves a request here and is called back when a matching cacheline appears. The queue, its lock, its counters and the rule for deciding which waiters a publication satisfies are cache state, and this is where they live.

What is deliberately NOT here: how the "a cacheline became ready" fact travels, and what a pending queue looks like to the user. Those belong to whoever is running the cache. develop/ still owns both, because the transport must stay ASYNCHRONOUS and that is not a style preference – the ready fact is emitted from dt_dev_pixelpipe_cache_wrlock_entry(FALSE, ...), which _cache_try_rekey_reuse_locked() calls while holding the process-wide ‘cache->lock’. Restart callbacks re-enter the cache. Serving them inline would re-lock a non-recursive mutex on the same thread and hang the pipeline worker holding it, taking every other pipe with it.

So this module hands back the list of waiters a publication satisfies and lets the caller run them, on whatever thread the caller has already arranged to be safe.

Definition in file pixelpipe_cache_wait.h.

Typedef Documentation

◆ dt_pixelpipe_cache_ready_callback_t

typedef void(* dt_pixelpipe_cache_ready_callback_t) (gpointer user_data)

Called when the awaited cacheline finally exists. Runs on the caller's thread.

Definition at line 51 of file pixelpipe_cache_wait.h.

◆ dt_pixelpipe_cache_wait_t

One consumer's outstanding request, owned by that consumer, not by the queue.

Callers embed this (dt_develop_t holds two) or keep one per widget, and hand its address in. The queue only ever links it, matches it and hands it back.

◆ dt_pixelpipe_cache_wait_visitor_t

typedef void(* dt_pixelpipe_cache_wait_visitor_t) (const dt_pixelpipe_cache_wait_t *wait, int64_t age_us, gpointer user_data)

Walk the outstanding requests. callback is invoked under the queue lock, so it must not re-enter this module or the cache.

Definition at line 136 of file pixelpipe_cache_wait.h.

Function Documentation

◆ dt_pixelpipe_cache_wait_cancel()

gboolean dt_pixelpipe_cache_wait_cancel ( dt_pixelpipe_cache_wait_t wait,
gboolean *  drained 
)

Remove wait from the queue if it is there, and reset it to an inert state.

Parameters
drainedSet to TRUE when this emptied the queue.
Returns
TRUE when the wait was actually queued and has now been removed.

Definition at line 145 of file pixelpipe_cache_wait.c.

References _find_locked(), _queue, _unlink_locked(), dt_pixelpipe_cache_wait_queue_t::cancelled_requests, dt_pixelpipe_cache_wait_t::connected, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, IS_NULL_PTR, L, dt_pixelpipe_cache_wait_queue_t::lock, and dt_pixelpipe_cache_wait_queue_t::pending.

Referenced by dt_dev_pixelpipe_cache_wait_cleanup().

◆ dt_pixelpipe_cache_wait_count_immediate_hit()

void dt_pixelpipe_cache_wait_count_immediate_hit ( void  )

◆ dt_pixelpipe_cache_wait_count_miss()

void dt_pixelpipe_cache_wait_count_miss ( void  )

◆ dt_pixelpipe_cache_wait_enqueue()

gboolean dt_pixelpipe_cache_wait_enqueue ( dt_pixelpipe_cache_wait_t wait)

Queue wait, or refresh it in place if it is already queued for the same target.

Returns
TRUE when the queue went from empty to non-empty, so the caller can raise whatever "the user is waiting" state it owns. FALSE otherwise, including when the wait was already queued unchanged.

Definition at line 74 of file pixelpipe_cache_wait.c.

References _find_locked(), _queue, dt_pixelpipe_cache_wait_t::connected, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, IS_NULL_PTR, L, dt_pixelpipe_cache_wait_queue_t::lock, dt_pixelpipe_cache_wait_queue_t::next_request_id, dt_pixelpipe_cache_wait_queue_t::pending, dt_pixelpipe_cache_wait_queue_t::queued_requests, dt_pixelpipe_cache_wait_t::request_id, and TRUE.

Referenced by dt_dev_pixelpipe_cache_peek_gui().

◆ dt_pixelpipe_cache_wait_foreach_pending()

◆ dt_pixelpipe_cache_wait_get_stats()

◆ dt_pixelpipe_cache_wait_pending_count()

guint dt_pixelpipe_cache_wait_pending_count ( void  )

◆ dt_pixelpipe_cache_wait_take_matching()

GList * dt_pixelpipe_cache_wait_take_matching ( uint64_t  hash,
uint64_t  producer_node_key,
gboolean *  drained 
)

Take every waiter satisfied by a publication of hash from node producer_node_key.

Matches on the exact hash OR on the producing node, which is what makes the protocol survive hash drift. Removes them from the queue and marks them disconnected.

Parameters
drainedSet to TRUE when this emptied the queue.
Returns
A caller-owned GList of dt_pixelpipe_cache_wait_t*, to run and then free. Callbacks are deliberately NOT run here: see the file comment on why the caller owns that step.

Definition at line 110 of file pixelpipe_cache_wait.c.

References _queue, _unlink_locked(), dt_pixelpipe_cache_wait_t::connected, DT_PIXELPIPE_CACHE_HASH_INVALID, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, dt_pixelpipe_cache_wait_t::hash, IS_NULL_PTR, L, dt_pixelpipe_cache_wait_queue_t::lock, dt_pixelpipe_cache_wait_queue_t::pending, dt_pixelpipe_cache_wait_queue_t::served_requests, and dt_pixelpipe_cache_wait_t::target_node_key.

Referenced by _dt_dev_pixelpipe_cache_wait_ready_callback().