## 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 *   (*VipsThreadStartFn)                (VipsImage *im,
                                                             void *a);
    int                 (*VipsThreadpoolAllocateFn)         (VipsThreadState *state,
                                                             void *a,
                                                             gboolean *stop);
    int                 (*VipsThreadpoolWorkFn)             (VipsThreadState *state,
                                                             void *a);
    int                 (*VipsThreadpoolProgressFn)         (void *a);
    int                 vips_threadpool_run                 (VipsImage *im,
                                                             VipsThreadStartFn start,
                                                             VipsThreadpoolAllocateFn allocate,
                                                             VipsThreadpoolWorkFn work,
                                                             VipsThreadpoolProgressFn progress,
                                                             void *a);
    void                vips_get_tile_size                  (VipsImage *im,
                                                             int *tile_width,
                                                             int *tile_height,
                                                             int *nlines);
    void                vips__print_renders                 (void);
    void                vips_concurrency_set                (int concurrency);
    int                 vips_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.
    	 */
    	VipsRegion *reg;

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

    	/* Set in work to get the allocate to signal stop.
    	 */
    	gboolean stop;

    	/* 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
VipsRegion *`reg`; | a REGION
VipsRect `pos`; | a Rect
int `x`; | an int
int `y`; | an int
gboolean `stop`; |
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);

### VipsThreadStartFn ()

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

### VipsThreadpoolAllocateFn ()

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

This function is called to allocate a new work unit for the thread. It is always single-threaded, so it can modify per-pool state (such as a counter).

`a`, `b`, `c` are the values supplied to the call to `vips_threadpool_run()`.

It should set `stop` to `TRUE` to indicate that no work could be allocated because the job is done.

See also: `vips_threadpool_run()`.

`state` : | per-thread state
`a` : | client data
`stop` : | set this to signal end of computation
Returns : | 0 on success, or -1 on error

### VipsThreadpoolWorkFn ()

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

This function is called to process a work unit. Many copies of this can run at once, so it should not write to the per-pool state. It can write to per-thread state.

`a`, `b`, `c` are the values supplied to the call to `vips_threadpool_run()`.

See also: `vips_threadpool_run()`.

`state` : | per-thread state
`a` : | client data
Returns : | 0 on success, or -1 on error

### VipsThreadpoolProgressFn ()

    int                 (*VipsThreadpoolProgressFn)         (void *a);

This function is called by the main thread once for every work unit processed. It can be used to give the user progress feedback.

See also: `vips_threadpool_run()`.

`a` : | client data
Returns : | 0 on success, or -1 on error

### vips_threadpool_run ()

    int                 vips_threadpool_run                 (VipsImage *im,
                                                             VipsThreadStartFn start,
                                                             VipsThreadpoolAllocateFn allocate,
                                                             VipsThreadpoolWorkFn work,
                                                             VipsThreadpoolProgressFn 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`.

The object returned by `start` must be an instance of a subclass of VipsThreadState. Use this to communicate between `allocate` and `work`.

`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: `vips_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 `vips_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

### vips__print_renders ()

    void                vips__print_renders                 (void);

### vips_concurrency_set ()

    void                vips_concurrency_set                (int concurrency);

Sets the number of worker threads that vips should use when running a VipsThreadPool.

The special value 0 means "default". In this case, the number of threads is set by the environmnt variable IM_CONCURRENCY, or if that is not set, the number of threads availble on the hist machine.

See also: `vips_concurrency_get()`.

`concurrency` : | number of threads to run

### vips_concurrency_get ()

    int                 vips_concurrency_get                (void);

Returns the number of worker threads that vips should use when running a VipsThreadPool.

vips gets this values from these sources in turn:

If `vips_concurrency_set()` has been called, this value is used. The special value 0 means "default". You can also use the command-line argument "--vips-concurrency" to set this value.

If `vips_concurrency_set()` has not been called and no command-line argument was used, vips uses the value of the environment variable IM_CONCURRENCY,

If IM_CONCURRENCY has not been set, vips find the number of hardware threads that the host machine can run in parallel and uses that value.

The final value is clipped to the range 1 - 1024.

See also: `vips_concurrency_get()`.

Returns : | number of worker threads to use.

## See Also

generate