1 /* Thread eval for VIPS.
2  *
3  * 29/9/99 JC
4  *	- from thread.h
5  * 17/3/10
6  * 	- from threadgroup
7  * 	- rework with a simpler distributed work allocation model
8  * 02/02/20 kleisauke
9  * 	- reuse threads by using GLib's threadpool
10  */
11 
12 /*
13 
14     This file is part of VIPS.
15 
16     VIPS is free software; you can redistribute it and/or modify
17     it under the terms of the GNU Lesser General Public License as published by
18     the Free Software Foundation; either version 2 of the License, or
19     (at your option) any later version.
20 
21     This program is distributed in the hope that it will be useful,
22     but WITHOUT ANY WARRANTY; without even the implied warranty of
23     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24     GNU Lesser General Public License for more details.
25 
26     You should have received a copy of the GNU Lesser General Public License
27     along with this program; if not, write to the Free Software
28     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29     02110-1301  USA
30 
31  */
32 
33 /*
34 
35     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
36 
37  */
38 
39 #ifndef VIPS_THREADPOOL_H
40 #define VIPS_THREADPOOL_H
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif /*__cplusplus*/
45 
46 #include <vips/semaphore.h>
47 
48 /* Per-thread state. Allocate functions can use these members to
49  * communicate with work functions.
50  */
51 
52 #define VIPS_TYPE_THREAD_STATE (vips_thread_state_get_type())
53 #define VIPS_THREAD_STATE( obj ) \
54 	(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
55 	VIPS_TYPE_THREAD_STATE, VipsThreadState ))
56 #define VIPS_THREAD_STATE_CLASS( klass ) \
57 	(G_TYPE_CHECK_CLASS_CAST( (klass), \
58 	VIPS_TYPE_THREAD_STATE, VipsThreadStateClass))
59 #define VIPS_IS_THREAD_STATE( obj ) \
60 	(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_THREAD_STATE ))
61 #define VIPS_IS_THREAD_STATE_CLASS( klass ) \
62 	(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_THREAD_STATE ))
63 #define VIPS_THREAD_STATE_GET_CLASS( obj ) \
64 	(G_TYPE_INSTANCE_GET_CLASS( (obj), \
65 	VIPS_TYPE_THREAD_STATE, VipsThreadStateClass ))
66 
67 typedef struct _VipsThreadState {
68 	VipsObject parent_object;
69 
70 	/*< public >*/
71 	/* Image we run on.
72 	 */
73 	VipsImage *im;
74 
75 	/* This region is created and destroyed by the threadpool for the
76 	 * use of the worker.
77 	 */
78 	VipsRegion *reg;
79 
80 	/* Neither used nor set, do what you like with them.
81 	 */
82 	VipsRect pos;
83 	int x, y;
84 
85 	/* Set in work to get the allocate to signal stop.
86 	 */
87 	gboolean stop;
88 
89 	/* The client data passed to the enclosing vips_threadpool_run().
90 	 */
91         void *a;
92 
93 	/* Set in allocate to stall this thread for a moment. Handy for
94 	 * debugging race conditions.
95 	 */
96 	gboolean stall;
97 
98 } VipsThreadState;
99 
100 typedef struct _VipsThreadStateClass {
101 	VipsObjectClass parent_class;
102 	/*< public >*/
103 
104 } VipsThreadStateClass;
105 
106 void *vips_thread_state_set( VipsObject *object, void *a, void *b );
107 
108 /* Don't put spaces around void here, it breaks gtk-doc.
109  */
110 GType vips_thread_state_get_type(void);
111 
112 VipsThreadState *vips_thread_state_new( VipsImage *im, void *a );
113 
114 /* Constructor for per-thread state.
115  */
116 typedef VipsThreadState *(*VipsThreadStartFn)( VipsImage *im, void *a );
117 
118 /* A work allocate function. This is run single-threaded by a worker to
119  * set up a new work unit.
120  * Return non-zero for errors. Set *stop for "no more work to do"
121  */
122 typedef int (*VipsThreadpoolAllocateFn)( VipsThreadState *state,
123 	void *a, gboolean *stop );
124 
125 /* A work function. This does a unit of work (eg. processing a tile or
126  * whatever). Return non-zero for errors.
127  */
128 typedef int (*VipsThreadpoolWorkFn)( VipsThreadState *state, void *a );
129 
130 /* A progress function. This is run by the main thread once for every
131  * allocation. Return an error to kill computation early.
132  */
133 typedef int (*VipsThreadpoolProgressFn)( void *a );
134 
135 int vips_threadpool_run( VipsImage *im,
136 	VipsThreadStartFn start,
137 	VipsThreadpoolAllocateFn allocate,
138 	VipsThreadpoolWorkFn work,
139 	VipsThreadpoolProgressFn progress,
140 	void *a );
141 void vips_get_tile_size( VipsImage *im,
142 	int *tile_width, int *tile_height, int *n_lines );
143 
144 #ifdef __cplusplus
145 }
146 #endif /*__cplusplus*/
147 
148 #endif /*VIPS_THREADPOOL_H*/
149