VipsThreadState

VipsThreadState — pools of worker threads

Stability Level

Stable, unless otherwise indicated

Synopsis

#include <vips/vips.h>

                    VipsThreadState;
                    VipsThreadStateClass;
void *              vips_thread_state_set               (VipsObject *object,
                                                         void *a,
                                                         void *b);
VipsThreadState *   vips_thread_state_new               (VipsImage *im,
                                                         void *a);
VipsThreadState *   (*VipsThreadStart)                  (VipsImage *im,
                                                         void *a);
int                 (*VipsThreadpoolAllocate)           (VipsThreadState *state,
                                                         void *a,
                                                         gboolean *stop);
int                 (*VipsThreadpoolWork)               (VipsThreadState *state,
                                                         void *a);
int                 (*VipsThreadpoolProgress)           (void *a);
int                 vips_threadpool_run                 (VipsImage *im,
                                                         VipsThreadStart start,
                                                         VipsThreadpoolAllocate allocate,
                                                         VipsThreadpoolWork work,
                                                         VipsThreadpoolProgress progress,
                                                         void *a);
void                vips_get_tile_size                  (VipsImage *im,
                                                         int *tile_width,
                                                         int *tile_height,
                                                         int *nlines);
int                 (*VipsRegionWrite)                  (REGION *region,
                                                         Rect *area,
                                                         void *a);
int                 vips_sink_disc                      (VipsImage *im,
                                                         VipsRegionWrite write_fn,
                                                         void *a);
void *              (*VipsStart)                        (VipsImage *out,
                                                         void *a,
                                                         void *b);
int                 (*VipsGenerate)                     (REGION *out,
                                                         void *seq,
                                                         void *a,
                                                         void *b);
int                 (*VipsStop)                         (void *seq,
                                                         void *a,
                                                         void *b);
int                 vips_sink                           (VipsImage *im,
                                                         VipsStart start,
                                                         VipsGenerate generate,
                                                         VipsStop stop,
                                                         void *a,
                                                         void *b);
int                 vips_sink_tile                      (VipsImage *im,
                                                         int tile_width,
                                                         int tile_height,
                                                         VipsStart start,
                                                         VipsGenerate generate,
                                                         VipsStop stop,
                                                         void *a,
                                                         void *b);
void                (*VipsSinkNotify)                   (VipsImage *im,
                                                         Rect *rect,
                                                         void *a);
int                 vips_sink_screen                    (VipsImage *in,
                                                         VipsImage *out,
                                                         VipsImage *mask,
                                                         int tile_width,
                                                         int tile_height,
                                                         int max_tiles,
                                                         int priority,
                                                         VipsSinkNotify notify,
                                                         void *a);
int                 vips_sink_memory                    (VipsImage *im);
void                im__print_renders                   (void);
void                im_concurrency_set                  (int concurrency);
int                 im_concurrency_get                  (void);

Object Hierarchy

  GObject
   +----VipsObject
         +----VipsThreadState

Description

vips_threadpool_run() loops a set of threads over an image. Threads take it in turns to allocate units of work (a unit might be a tile in an image), then run in parallel to process those units. An optional progress function can be used to give feedback.

Details

VipsThreadState

typedef struct {
	/* Image we run on.
	 */
	VipsImage *im;

	/* This region is created and destroyed by the threadpool for the
	 * use of the worker. 
	 */
	REGION *reg;		

	/* Neither used nor set, do what you like with them.
	 */
	Rect pos;
	int x, y;

	/* The client data passed to the enclosing vips_threadpool_run().
	 */
        void *a;
} VipsThreadState;

These per-thread values are carried around for your use by vips_threadpool_run(). They are private to each thread, so they are a useful place for VipsThreadpoolAllocate and VipsThreadpoolWork to communicate.

reg is created for you at the start of processing and freed at the end, but you can do what you like with it.

VipsImage *im;

the VipsImage being operated upon

REGION *reg;

a REGION

Rect pos;

a Rect

int x;

an int

int y;

an int

void *a;

client data

VipsThreadStateClass

typedef struct {
	VipsObjectClass parent_class;
} VipsThreadStateClass;

vips_thread_state_set ()

void *              vips_thread_state_set               (VipsObject *object,
                                                         void *a,
                                                         void *b);

vips_thread_state_new ()

VipsThreadState *   vips_thread_state_new               (VipsImage *im,
                                                         void *a);

VipsThreadStart ()

VipsThreadState *   (*VipsThreadStart)                  (VipsImage *im,
                                                         void *a);

VipsThreadpoolAllocate ()

int                 (*VipsThreadpoolAllocate)           (VipsThreadState *state,
                                                         void *a,
                                                         gboolean *stop);

VipsThreadpoolWork ()

int                 (*VipsThreadpoolWork)               (VipsThreadState *state,
                                                         void *a);

VipsThreadpoolProgress ()

int                 (*VipsThreadpoolProgress)           (void *a);

vips_threadpool_run ()

int                 vips_threadpool_run                 (VipsImage *im,
                                                         VipsThreadStart start,
                                                         VipsThreadpoolAllocate allocate,
                                                         VipsThreadpoolWork work,
                                                         VipsThreadpoolProgress progress,
                                                         void *a);

This function runs a set of threads over an image. Each thread first calls start to create new per-thread state, then runs allocate to set up a new work unit (perhaps the next tile in an image, for example), then work to process that work unit. After each unit is processed, progress is called, so that the operation can give progress feedback. progress may be NULL.

Each thread has private state that the allocate and work functions can use to communicate. This state is created by each worker as it starts using start. Use the state destructor to clean up.

allocate and start are always single-threaded (so they can write to the per-pool state), whereas work can be executed concurrently. progress is always called by the main thread (ie. the thread which called vips_threadpool_run()).

See also: im_wbuffer2(), im_concurrency_set().

im :

image to loop over

start :

allocate per-thread state

allocate :

allocate a work unit

work :

process a work unit

progress :

give progress feedback about a work unit, or NULL

a :

client data

Returns :

0 on success, or -1 on error.

vips_get_tile_size ()

void                vips_get_tile_size                  (VipsImage *im,
                                                         int *tile_width,
                                                         int *tile_height,
                                                         int *nlines);

Pick a tile size and a buffer height for this image and the current value of im_concurrency_get(). The buffer height will always be a multiple of tile_height.

im :

image to guess for

tile_width :

return selected tile width

tile_height :

return selected tile height

nlines :

return buffer height in scanlines

VipsRegionWrite ()

int                 (*VipsRegionWrite)                  (REGION *region,
                                                         Rect *area,
                                                         void *a);

The function should write the pixels in area from region. a is the value passed into vips_discsink().

See also: vips_discsink().

region :

get pixels from here

area :

area to write

a :

client data

Returns :

0 on success, -1 on error.

vips_sink_disc ()

int                 vips_sink_disc                      (VipsImage *im,
                                                         VipsRegionWrite write_fn,
                                                         void *a);

vips_sink_disc() loops over im, top-to-bottom, generating it in sections. As each section is produced, write_fn is called.

write_fn is always called single-threaded (though not always from the same thread), it's always given image sections in top-to-bottom order, and there are never any gaps.

This operation is handy for making image sinks which output to things like disc files.

See also: im_concurrency_set().

im :

image to process

write_fn :

called for every batch of pixels

a :

client data

Returns :

0 on success, -1 on error.

VipsStart ()

void *              (*VipsStart)                        (VipsImage *out,
                                                         void *a,
                                                         void *b);

VipsGenerate ()

int                 (*VipsGenerate)                     (REGION *out,
                                                         void *seq,
                                                         void *a,
                                                         void *b);

VipsStop ()

int                 (*VipsStop)                         (void *seq,
                                                         void *a,
                                                         void *b);

vips_sink ()

int                 vips_sink                           (VipsImage *im,
                                                         VipsStart start,
                                                         VipsGenerate generate,
                                                         VipsStop stop,
                                                         void *a,
                                                         void *b);

Loops over an image. generate is called for every pixel in the image, with the reg argument being a region of pixels for processing. vips_sink() is used to implement operations like im_avg() which have no image output.

Each set of pixels is sized according to the requirements of the image pipeline that generated im.

See also: im_generate(), im_open().

im :

scan over this image

start :

start sequences with this function

generate :

generate pixels with this function

stop :

stop sequences with this function

a :

user data

b :

user data

Returns :

0 on success, or -1 on error.

vips_sink_tile ()

int                 vips_sink_tile                      (VipsImage *im,
                                                         int tile_width,
                                                         int tile_height,
                                                         VipsStart start,
                                                         VipsGenerate generate,
                                                         VipsStop stop,
                                                         void *a,
                                                         void *b);

Loops over an image. generate is called for every pixel in the image, with the reg argument being a region of pixels for processing. vips_sink_tile() is used to implement operations like im_avg() which have no image output.

Each set of pixels is tile_width by tile_height pixels (less at the image edges). This is handy for things like writing a tiled TIFF image, where tiles have to be generated with a certain size.

See also: vips_sink(), vips_get_tile_size().

im :

scan over this image

tile_width :

tile width

tile_height :

tile height

start :

start sequences with this function

generate :

generate pixels with this function

stop :

stop sequences with this function

a :

user data

b :

user data

Returns :

0 on success, or -1 on error.

VipsSinkNotify ()

void                (*VipsSinkNotify)                   (VipsImage *im,
                                                         Rect *rect,
                                                         void *a);

vips_sink_screen ()

int                 vips_sink_screen                    (VipsImage *in,
                                                         VipsImage *out,
                                                         VipsImage *mask,
                                                         int tile_width,
                                                         int tile_height,
                                                         int max_tiles,
                                                         int priority,
                                                         VipsSinkNotify notify,
                                                         void *a);

This operation renders in in the background, making pixels available on out as they are calculated. The notify callback is run every time a new set of pixels are available. Calculated pixels are kept in a cache with tiles sized tile_width by tile_height pixels and with at most max_tiles tiles. If max_tiles is -1, the cache is of unlimited size (up to the maximum image size). The mask image is a one-band uchar image and has 255 for pixels which are currently in cache and 0 for uncalculated pixels.

Only a single sink is calculated at any one time, though many may be alive. Use priority to indicate which renders are more important: zero means normal priority, negative numbers are low priority, positive numbers high priority.

Calls to im_prepare() on out return immediately and hold whatever is currently in cache for that Rect (check mask to see which parts of the Rect are valid). Any pixels in the Rect which are not in cache are added to a queue, and the notify callback will trigger when those pixels are ready.

The notify callback is run from one of the background threads. In the callback you need to somehow send a message to the main thread that the pixels are ready. In a glib-based application, this is easily done with g_idle_add().

If notify is NULL then im_render_priority() runs synchronously. im_prepare() on out will always block until the pixels have been calculated.

See also: im_cache(), im_prepare(), vips_sink_disc(), vips_sink().

in :

input image

out :

output image

mask :

mask image indicating valid pixels

tile_width :

tile width

tile_height :

tile height

max_tiles :

maximum tiles to cache

priority :

rendering priority

notify :

pixels are ready notification callback

a :

client data for callback

Returns :

0 on sucess, -1 on error.

vips_sink_memory ()

int                 vips_sink_memory                    (VipsImage *im);

Loops over an image, generating it to a memory buffer attached to the image.

See also: vips_sink(), vips_get_tile_size().

im :

generate this image to memory

Returns :

0 on success, or -1 on error.

im__print_renders ()

void                im__print_renders                   (void);

im_concurrency_set ()

void                im_concurrency_set                  (int concurrency);

im_concurrency_get ()

int                 im_concurrency_get                  (void);

See Also

generate