HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_ThreadedAlgorithm.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_ThreadedAlgorithm.h ( SIM Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __UT_ThreadedAlgorithm__
12 #define __UT_ThreadedAlgorithm__
13 
14 #include "UT_API.h"
15 
16 class UT_JobInfo;
17 
18 #include <SYS/SYS_AtomicInt.h>
19 #include "UT_Thread.h"
20 #include "UT_Lock.h"
21 #include "UT_Functor.h"
22 
23 #if !defined(GAMEOS)
24 #include <hboost/tuple/tuple.hpp>
25 #endif
26 
27 ///
28 /// UT_ThreadedAlgorithm takes care of all the thread administration that a
29 /// threaded algorithm requires.
30 ///
31 /// Its features are:
32 /// 1) it executes work in the main thread as well
33 /// 2) it assumes that the work can be divided into N parts and sends off
34 /// exactly N calls to threadfunc() (jobs). (N depends on the # of
35 /// installed processors and the maxthreads parm).
36 ///
37 /// Your callback function is called with several
38 /// useful parameters:
39 ///
40 /// void * data - the userdata pointer you provide to run()
41 /// int jobindex - there are N jobs, this is which job you're running
42 /// (0 to N-1).
43 /// int maxindex - the total number of jobs farmed (N)
44 /// UT_Lock &lock - a lock that you can use to lock other jobs out while
45 /// you work on something non-threadsafe. Accepts NULL.
46 ///
47 /// If your machine is a single proc, this will work exactly as a call to
48 /// threadfunc().
49 ///
50 /// In addition to the traditional threadfunc() callback, you can pass
51 /// in a UT_Functor1 which takes a UT_JobInfo parameter to specify the
52 /// job to be performed (see below). In this case, you may be better off
53 /// with the THREADED_METHOD macros detailed later.
54 ///
56 {
57 public:
58  UT_ThreadedAlgorithm(int maxthreads = -1);
60 
61  /// Starts the jobs, and waits until all are finished. This can be called
62  /// multiple times. The optional lock parm allows you to use your own
63  /// lock; if not specified, this class's lock will be used.
64  void run(void (*threadfunc)(void *, int, int, UT_Lock &),
65  void *userdata,
66  UT_Lock *lock = 0);
67 
68  /// Starts the jobs and waits until all are finished.
69  /// Since this uses a functor, you are expected to use BindFirst
70  /// to hide any user data you may have
71  /// While a return type is specified, it is not used. This is because
72  /// compiler bugs prohibit a Functor2 that returns null.
73  void run(UT_Functor1<int, const UT_JobInfo &> functor,
74  UT_Lock *lock = 0);
75 
76 private:
77  UT_Lock *myLock;
78  int myThreadCount;
79  bool myIsRoot;
80  static SYS_AtomicInt32 ourThreadedAlgorithmInUse;
81 };
82 
83 ///
84 /// Defines the work required for each invocation of *Partial
85 /// to complete.
86 ///
88 {
89 public:
90  UT_JobInfo(int jobidx, int numjobs, UT_Lock *lock, SYS_AtomicInt32 *aint = 0)
91  {
92  myJob = jobidx;
93  myNumJobs = numjobs;
94  myLock = lock;
95  myTask = aint;
96  myLocalTask = 0;
97  }
98 
99  /// The number of jobs is the total number of threads
100  /// that is running and job() is your thread #, starting at 0
101  /// and going up to numJobs()-1
102  int job() const { return myJob; }
103  int numJobs() const { return myNumJobs; }
104 
105  /// These control a shared AtomicInt32 so you can split
106  /// tasks among jobs using load balancing. The total number
107  /// is in this case up to you to detect.
108  /// The JobIds will start with 0 and each call will get a unique
109  /// higher number.
110  /// Example:
111  /// for (i = info.nextTask(); i < maxtask; i = info.nextTask())
112  int32 nextTask() const;
113 
114  /// Resets the task list. You are responsible for creating
115  /// a barrier to ensure that all the other threads have
116  /// hit the end of the tasks!
117  /// This is *not* required for your first loop as you will
118  /// already start at task 0.
119  void resetTasks() const;
120 
121  /// Given "units" work, report which units you are responsible
122  /// for with this JobInfo. The resulting interval is [start, end),
123  /// Appropriate for loop:
124  /// for (info.divideWork(total, i, end); i < end; i++)
125  void divideWork(int units, int &start, int &end) const;
126  void divideWork(exint units, exint &start, exint &end) const;
127 
128  /// lock and unlock a lock shared by all the jobs. This lock
129  /// is special cased to a no-op in the threadless case to avoid
130  /// overhead.
131  void lock() const
132  {
133  if (myLock)
134  myLock->lock();
135  }
136  void unlock() const
137  {
138  if (myLock)
139  myLock->unlock();
140  }
141 
142 protected:
143  int myJob, myNumJobs;
146  mutable int myLocalTask;
147 };
148 
150 {
151 public:
153  : myLock(lock)
154  { lock.lock(); }
155 
156  ~UT_AutoJobInfoLock() { myLock.unlock(); }
157 
158 private:
159  const UT_JobInfo &myLock;
160 };
161 
162 ///
163 /// @file
164 /// This macro is equivalent to
165 /// @code
166 /// for (i = 0; i < n; i++)
167 /// @endcode
168 ///
169 /// It will, however break it into BLOCK sized chunks for each thread,
170 /// allowing for load balancing
171 /// NB: Because it relies on the info.nextTask() starting at zero, you
172 /// can only loop once in this manner.
173 /// NB: This is a double loop, so break; does not work as you expect.
174 /// NB: The iterator, i, does not have to be defined.
175 /// An example of use:
176 ///
177 /// @code
178 /// FOR_INFOTASKS(info, i, n, 100)
179 /// {
180 /// // Process task i.
181 /// }
182 /// @endcode
183 ///
184 /// If you want opInterrupt() triggered for every block completed,
185 ///
186 /// @code
187 /// FOR_INFOTASKS_BOSS(info, i, n, 100, boss)
188 /// {
189 /// // Process task i.
190 /// }
191 /// @endcode
192 ///
193 #define FOR_INFOTASKS(info, i, n, blocksize) \
194 for (int task = info.nextTask() * blocksize; task < n; task = info.nextTask() * blocksize) \
195  for (int i = task, lcl_final = SYSmin(task+blocksize, (int)n); i < lcl_final; i++)
196 
197 #define FOR_INFOTASKS_BOSS(info, i, n, blocksize, boss) \
198 for (int task = info.nextTask() * blocksize; task < n && !boss->opInterrupt(); task = info.nextTask() * blocksize) \
199  for (int i = task, lcl_final = SYSmin(task+blocksize, (int)n); i < lcl_final; i++)
200 
201 
202 ///
203 /// @file
204 /// These macros automatically create all the wrapper functions
205 /// required to set up a multithreaded function call that can
206 /// be invoked transparently.
207 ///
208 /// An example of use:
209 /// @code
210 /// class Foobar
211 /// {
212 /// ...
213 /// THREADED_METHOD2(Foobar, gdp->points().entries() > 100,
214 /// translate,
215 /// GU_Detail *, gdp,
216 /// const UT_Vector3 &, delta)
217 ///
218 /// void translatePartial(GU_Detail *gdp, const UT_Vector3 &delta,
219 /// const UT_JobInfo &info);
220 /// ...
221 /// }
222 ///
223 /// void
224 /// Foobar::translatePartial(GU_Detail *gdp, const UT_Vector3 &delta,
225 /// const UT_JobInfo &info)
226 /// {
227 /// int i, n;
228 ///
229 /// for (info.divideWork(gdp->points().entries, i, n); i < n; i++)
230 /// {
231 /// gdp->points()(i).getPos() += delta;
232 /// }
233 /// }
234 /// @endcode
235 ///
236 /// The suffix number is the number of parameters the function
237 /// should take - THREADED_METHOD#(). The parameters to the macro are:
238 ///
239 /// @code
240 /// THREADED_METHOD#(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, ...);
241 /// @endcode
242 ///
243 /// The DOMULTI is a boolean value (which may be a function returning
244 /// such) which determines if multithreading should be performed.
245 /// This lets you disable the multithreading for small batches.
246 /// Note it executes inside of METHOD, so has access to the parameters
247 /// in the CLASS. For threaded methods with parameters, you need to
248 /// specify both the PARMTYPE and the PARMNAME for each parameter.
249 ///
250 /// The user must both prototype & implement a
251 /// @code
252 /// void functionPartial(parameterlist, const &UT_JobInfo)
253 /// @endcode
254 /// which does all the real work (see above).
255 ///
256 /// Automatically created by the THREADED_METHOD macro are:
257 /// @code
258 /// void function(parameterlist) <- what users can invoke
259 /// void functionNoThread(parameterlist) <- unthreaded version
260 /// int functionInvokeParital(...) <- marshalling function.
261 /// @endcode
262 ///
263 
264 // The linux ia64 compiler doesn't like functors very much, so
265 // we hide them from it.
266 #if defined(IA64) || defined(GAMEOS)
267 
268 #define THREADED_METHOD_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD) \
269 void METHOD() ISCONST \
270 { \
271  METHOD ## NoThread(); \
272 } \
273  \
274 void METHOD ## NoThread() ISCONST \
275 { \
276  METHOD ## Partial(UT_JobInfo(0, 1, 0)); \
277 }
278 
279 #define THREADED_METHOD1_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1) \
280 void METHOD(PARMTYPE1 PARMNAME1) ISCONST \
281 { \
282  METHOD ## NoThread(PARMNAME1); \
283 } \
284  \
285 void METHOD ## NoThread(PARMTYPE1 PARMNAME1) ISCONST \
286 { \
287  METHOD ## Partial(PARMNAME1, UT_JobInfo(0, 1, 0)); \
288 }
289 
290 #define THREADED_METHOD2_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2) \
291 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2) ISCONST \
292 { \
293  METHOD ## NoThread(PARMNAME1, PARMNAME2); \
294 } \
295  \
296 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2) ISCONST \
297 { \
298  METHOD ## Partial(PARMNAME1, PARMNAME2, UT_JobInfo(0, 1, 0)); \
299 }
300 
301 #define THREADED_METHOD3_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3) \
302 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3) ISCONST \
303 { \
304  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3); \
305 } \
306  \
307 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3) ISCONST \
308 { \
309  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, UT_JobInfo(0, 1, 0)); \
310 }
311 
312 #define THREADED_METHOD4_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4) \
313 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4) ISCONST \
314 { \
315  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4); \
316 } \
317  \
318 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4) ISCONST \
319 { \
320  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, UT_JobInfo(0, 1, 0)); \
321 }
322 
323 #define THREADED_METHOD5_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5) \
324 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5) ISCONST \
325 { \
326  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5); \
327 } \
328  \
329 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5) ISCONST \
330 { \
331  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, UT_JobInfo(0, 1, 0)); \
332 }
333 
334 #define THREADED_METHOD6_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6) \
335 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6) ISCONST \
336 { \
337  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6); \
338 } \
339  \
340 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6) ISCONST \
341 { \
342  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, UT_JobInfo(0, 1, 0)); \
343 }
344 
345 #define THREADED_METHOD7_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7) \
346 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7) ISCONST \
347 { \
348  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7); \
349 } \
350  \
351 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7) ISCONST \
352 { \
353  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, UT_JobInfo(0, 1, 0)); \
354 }
355 
356 #define THREADED_METHOD8_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8) \
357 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7, PARMTYPE8 PARMNAME8) ISCONST \
358 { \
359  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8); \
360 } \
361  \
362 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7, PARMTYPE8 PARMNAME8) ISCONST \
363 { \
364  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8, UT_JobInfo(0, 1, 0)); \
365 }
366 
367 #else
368 
369 #define THREADED_METHOD_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD) \
370 void METHOD() ISCONST \
371 { \
372  if (!(DOMULTI)) \
373  { \
374  METHOD ## NoThread(); \
375  return; \
376  } \
377  \
378  UT_Functor1<int, const UT_JobInfo &> functor( \
379  this, &CLASSNAME::METHOD ## InvokePartial); \
380  UT_ThreadedAlgorithm alg; \
381  \
382  alg.run(functor); \
383  \
384 } \
385  \
386 void METHOD ## NoThread() ISCONST \
387 { \
388  METHOD ## Partial(UT_JobInfo(0, 1, 0)); \
389 } \
390  \
391 int METHOD ## InvokePartial(const UT_JobInfo &info) ISCONST \
392 { \
393  METHOD ## Partial(info); \
394  return 0; \
395 }
396 
397 #define THREADED_METHOD1_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1) \
398 void METHOD(PARMTYPE1 PARMNAME1) ISCONST \
399 { \
400  if (!(DOMULTI)) \
401  { \
402  METHOD ## NoThread(PARMNAME1); \
403  return; \
404  } \
405  \
406  UT_Functor2<int, PARMTYPE1, const UT_JobInfo &> functor( \
407  this, &CLASSNAME::METHOD ## InvokePartial); \
408  UT_ThreadedAlgorithm alg; \
409  \
410  alg.run(UT_BindFirst1(functor, PARMNAME1)); \
411  \
412 } \
413  \
414 void METHOD ## NoThread(PARMTYPE1 PARMNAME1) ISCONST \
415 { \
416  METHOD ## Partial(PARMNAME1, UT_JobInfo(0, 1, 0)); \
417 } \
418  \
419 int METHOD ## InvokePartial(PARMTYPE1 PARMNAME1, const UT_JobInfo &info) ISCONST \
420 { \
421  METHOD ## Partial(PARMNAME1, info); \
422  return 0; \
423 }
424 
425 #define THREADED_METHOD2_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2) \
426 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2) ISCONST \
427 { \
428  if (!(DOMULTI)) \
429  { \
430  METHOD ## NoThread(PARMNAME1, PARMNAME2); \
431  return; \
432  } \
433  \
434  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2 >, const UT_JobInfo &> functor( \
435  this, &CLASSNAME::METHOD ## InvokePartial); \
436  UT_ThreadedAlgorithm alg; \
437  \
438  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1, PARMTYPE2 >(PARMNAME1,PARMNAME2))); \
439  \
440 } \
441  \
442 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2) ISCONST \
443 { \
444  METHOD ## Partial(PARMNAME1, PARMNAME2, UT_JobInfo(0, 1, 0)); \
445 } \
446  \
447 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2 > tuple, const UT_JobInfo &info) ISCONST \
448 { \
449  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), info); \
450  return 0; \
451 }
452 
453 #define THREADED_METHOD3_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3) \
454 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3) ISCONST \
455 { \
456  if (!(DOMULTI)) \
457  { \
458  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3); \
459  return; \
460  } \
461  \
462  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3 >, const UT_JobInfo &> functor( \
463  this, &CLASSNAME::METHOD ## InvokePartial); \
464  UT_ThreadedAlgorithm alg; \
465  \
466  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3 >(PARMNAME1, PARMNAME2, PARMNAME3))); \
467  \
468 } \
469  \
470 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3) ISCONST \
471 { \
472  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, UT_JobInfo(0, 1, 0)); \
473 } \
474  \
475 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2, PARMTYPE3 > tuple, const UT_JobInfo &info) ISCONST \
476 { \
477  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), hboost::get<2>(tuple), info); \
478  return 0; \
479 }
480 
481 #define THREADED_METHOD4_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4) \
482 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4) ISCONST \
483 { \
484  if (!(DOMULTI)) \
485  { \
486  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4); \
487  return; \
488  } \
489  \
490  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4 >, const UT_JobInfo &> functor( \
491  this, &CLASSNAME::METHOD ## InvokePartial); \
492  UT_ThreadedAlgorithm alg; \
493  \
494  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4 >(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4))); \
495  \
496 } \
497  \
498 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4) ISCONST \
499 { \
500  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, UT_JobInfo(0, 1, 0)); \
501 } \
502  \
503 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2, PARMTYPE3, PARMTYPE4 > tuple, const UT_JobInfo &info) ISCONST \
504 { \
505  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), hboost::get<2>(tuple), hboost::get<3>(tuple), info); \
506  return 0; \
507 }
508 
509 
510 #define THREADED_METHOD5_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5) \
511 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5) ISCONST \
512 { \
513  if (!(DOMULTI)) \
514  { \
515  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5); \
516  return; \
517  } \
518  \
519  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5 >, const UT_JobInfo &> functor( \
520  this, &CLASSNAME::METHOD ## InvokePartial); \
521  UT_ThreadedAlgorithm alg; \
522  \
523  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5 >(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5))); \
524  \
525 } \
526  \
527 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5) ISCONST \
528 { \
529  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, UT_JobInfo(0, 1, 0)); \
530 } \
531  \
532 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2, PARMTYPE3, PARMTYPE4, PARMTYPE5 > tuple, const UT_JobInfo &info) ISCONST \
533 { \
534  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), hboost::get<2>(tuple), hboost::get<3>(tuple), hboost::get<4>(tuple), info); \
535  return 0; \
536 }
537 
538 
539 #define THREADED_METHOD6_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6) \
540 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6) ISCONST \
541 { \
542  if (!(DOMULTI)) \
543  { \
544  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6); \
545  return; \
546  } \
547  \
548  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6 >, const UT_JobInfo &> functor( \
549  this, &CLASSNAME::METHOD ## InvokePartial); \
550  UT_ThreadedAlgorithm alg; \
551  \
552  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6 >(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6))); \
553  \
554 } \
555  \
556 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6) ISCONST \
557 { \
558  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, UT_JobInfo(0, 1, 0)); \
559 } \
560  \
561 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2, PARMTYPE3, PARMTYPE4, PARMTYPE5, PARMTYPE6 > tuple, const UT_JobInfo &info) ISCONST \
562 { \
563  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), hboost::get<2>(tuple), hboost::get<3>(tuple), hboost::get<4>(tuple), hboost::get<5>(tuple), info); \
564  return 0; \
565 }
566 
567 #define THREADED_METHOD7_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7) \
568 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7) ISCONST \
569 { \
570  if (!(DOMULTI)) \
571  { \
572  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7); \
573  return; \
574  } \
575  \
576  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6,PARMTYPE7 >, const UT_JobInfo &> functor( \
577  this, &CLASSNAME::METHOD ## InvokePartial); \
578  UT_ThreadedAlgorithm alg; \
579  \
580  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6,PARMTYPE7 >(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7))); \
581  \
582 } \
583  \
584 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7) ISCONST \
585 { \
586  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, UT_JobInfo(0, 1, 0)); \
587 } \
588  \
589 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2, PARMTYPE3, PARMTYPE4, PARMTYPE5, PARMTYPE6, PARMTYPE7 > tuple, const UT_JobInfo &info) ISCONST \
590 { \
591  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), hboost::get<2>(tuple), hboost::get<3>(tuple), hboost::get<4>(tuple), hboost::get<5>(tuple), hboost::get<6>(tuple), info); \
592  return 0; \
593 }
594 
595 #define THREADED_METHOD8_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8) \
596 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7, PARMTYPE8 PARMNAME8) ISCONST \
597 { \
598  if (!(DOMULTI)) \
599  { \
600  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8); \
601  return; \
602  } \
603  \
604  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6,PARMTYPE7,PARMTYPE8 >, const UT_JobInfo &> functor( \
605  this, &CLASSNAME::METHOD ## InvokePartial); \
606  UT_ThreadedAlgorithm alg; \
607  \
608  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6,PARMTYPE7,PARMTYPE8 >(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8))); \
609  \
610 } \
611  \
612 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7, PARMTYPE8 PARMNAME8) ISCONST \
613 { \
614  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8, UT_JobInfo(0, 1, 0)); \
615 } \
616  \
617 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2, PARMTYPE3, PARMTYPE4, PARMTYPE5, PARMTYPE6, PARMTYPE7, PARMTYPE8 > tuple, const UT_JobInfo &info) ISCONST \
618 { \
619  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), hboost::get<2>(tuple), hboost::get<3>(tuple), hboost::get<4>(tuple), hboost::get<5>(tuple), hboost::get<6>(tuple), hboost::get<7>(tuple), info); \
620  return 0; \
621 }
622 
623 #define THREADED_METHOD9_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9) \
624 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7, PARMTYPE8 PARMNAME8, PARMTYPE9 PARMNAME9) ISCONST \
625 { \
626  if (!(DOMULTI)) \
627  { \
628  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8, PARMNAME9); \
629  return; \
630  } \
631  \
632  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6,PARMTYPE7,PARMTYPE8,PARMTYPE9 >, const UT_JobInfo &> functor( \
633  this, &CLASSNAME::METHOD ## InvokePartial); \
634  UT_ThreadedAlgorithm alg; \
635  \
636  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6,PARMTYPE7,PARMTYPE8,PARMTYPE9 >(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8, PARMNAME9))); \
637  \
638 } \
639  \
640 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7, PARMTYPE8 PARMNAME8, PARMTYPE9 PARMNAME9) ISCONST \
641 { \
642  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8, PARMNAME9, UT_JobInfo(0, 1, 0)); \
643 } \
644  \
645 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2, PARMTYPE3, PARMTYPE4, PARMTYPE5, PARMTYPE6, PARMTYPE7, PARMTYPE8, PARMTYPE9 > tuple, const UT_JobInfo &info) ISCONST \
646 { \
647  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), hboost::get<2>(tuple), hboost::get<3>(tuple), hboost::get<4>(tuple), hboost::get<5>(tuple), hboost::get<6>(tuple), hboost::get<7>(tuple), hboost::get<8>(tuple), info); \
648  return 0; \
649 }
650 
651 #define THREADED_METHOD10_INTERNAL(ISCONST, CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9, PARMTYPE10, PARMNAME10) \
652 void METHOD(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7, PARMTYPE8 PARMNAME8, PARMTYPE9 PARMNAME9, PARMTYPE10 PARMNAME10) ISCONST \
653 { \
654  if (!(DOMULTI)) \
655  { \
656  METHOD ## NoThread(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8, PARMNAME9, PARMNAME10); \
657  return; \
658  } \
659  \
660  UT_Functor2<int, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6,PARMTYPE7,PARMTYPE8,PARMTYPE9,PARMTYPE10 >, const UT_JobInfo &> functor( \
661  this, &CLASSNAME::METHOD ## InvokePartial); \
662  UT_ThreadedAlgorithm alg; \
663  \
664  alg.run(UT_BindFirst1(functor, hboost::tuple<PARMTYPE1,PARMTYPE2,PARMTYPE3,PARMTYPE4,PARMTYPE5,PARMTYPE6,PARMTYPE7,PARMTYPE8,PARMTYPE9,PARMTYPE10 >(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8, PARMNAME9, PARMNAME10))); \
665  \
666 } \
667  \
668 void METHOD ## NoThread(PARMTYPE1 PARMNAME1, PARMTYPE2 PARMNAME2, PARMTYPE3 PARMNAME3, PARMTYPE4 PARMNAME4, PARMTYPE5 PARMNAME5, PARMTYPE6 PARMNAME6, PARMTYPE7 PARMNAME7, PARMTYPE8 PARMNAME8, PARMTYPE9 PARMNAME9, PARMTYPE10 PARMNAME10) ISCONST \
669 { \
670  METHOD ## Partial(PARMNAME1, PARMNAME2, PARMNAME3, PARMNAME4, PARMNAME5, PARMNAME6, PARMNAME7, PARMNAME8, PARMNAME9, PARMNAME10, UT_JobInfo(0, 1, 0)); \
671 } \
672  \
673 int METHOD ## InvokePartial(hboost::tuple<PARMTYPE1, PARMTYPE2, PARMTYPE3, PARMTYPE4, PARMTYPE5, PARMTYPE6, PARMTYPE7, PARMTYPE8, PARMTYPE9, PARMTYPE10 > tuple, const UT_JobInfo &info) ISCONST \
674 { \
675  METHOD ## Partial(hboost::get<0>(tuple), hboost::get<1>(tuple), hboost::get<2>(tuple), hboost::get<3>(tuple), hboost::get<4>(tuple), hboost::get<5>(tuple), hboost::get<6>(tuple), hboost::get<7>(tuple), hboost::get<8>(tuple), hboost::get<9>(tuple), info); \
676  return 0; \
677 }
678 
679 
680 
681 #endif // Switch if we allow functors.
682 
683 #define THREADED_METHOD(CLASSNAME, DOMULTI, METHOD) \
684  THREADED_METHOD_INTERNAL( , CLASSNAME, DOMULTI, METHOD)
685 #define THREADED_METHOD_CONST(CLASSNAME, DOMULTI, METHOD) \
686  THREADED_METHOD_INTERNAL(const , CLASSNAME, DOMULTI, METHOD)
687 
688 #define THREADED_METHOD1(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1) \
689  THREADED_METHOD1_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
690 #define THREADED_METHOD1_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1) \
691  THREADED_METHOD1_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
692 
693 #define THREADED_METHOD2(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2) \
694  THREADED_METHOD2_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2)
695 #define THREADED_METHOD2_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2) \
696  THREADED_METHOD2_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2)
697 
698 #define THREADED_METHOD3(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3) \
699  THREADED_METHOD3_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3)
700 #define THREADED_METHOD3_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3) \
701  THREADED_METHOD3_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3)
702 
703 #define THREADED_METHOD4(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4) \
704  THREADED_METHOD4_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4)
705 #define THREADED_METHOD4_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4) \
706  THREADED_METHOD4_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4)
707 
708 #define THREADED_METHOD5(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5) \
709  THREADED_METHOD5_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5)
710 #define THREADED_METHOD5_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5) \
711  THREADED_METHOD5_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5)
712 
713 #define THREADED_METHOD6(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6) \
714  THREADED_METHOD6_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6)
715 #define THREADED_METHOD6_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6) \
716  THREADED_METHOD6_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6)
717 
718 #define THREADED_METHOD7(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7) \
719  THREADED_METHOD7_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7)
720 #define THREADED_METHOD7_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7) \
721  THREADED_METHOD7_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7)
722 
723 #define THREADED_METHOD8(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8) \
724  THREADED_METHOD8_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8)
725 #define THREADED_METHOD8_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8) \
726  THREADED_METHOD8_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8)
727 
728 #define THREADED_METHOD9(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9) \
729  THREADED_METHOD9_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9)
730 #define THREADED_METHOD9_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9) \
731  THREADED_METHOD9_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9)
732 
733 #define THREADED_METHOD10(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9, PARMTYPE10, PARMNAME10) \
734  THREADED_METHOD10_INTERNAL( , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9, PARMTYPE10, PARMNAME10)
735 #define THREADED_METHOD10_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9, PARMTYPE10, PARMNAME10) \
736  THREADED_METHOD10_INTERNAL(const , CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6, PARMTYPE7, PARMNAME7, PARMTYPE8, PARMNAME8, PARMTYPE9, PARMNAME9, PARMTYPE10, PARMNAME10)
737 
738 #endif
UT_JobInfo(int jobidx, int numjobs, UT_Lock *lock, SYS_AtomicInt32 *aint=0)
GLuint start
Definition: glcorearb.h:474
#define UT_API
Definition: UT_API.h:12
UT_AutoJobInfoLock(const UT_JobInfo &lock)
int64 exint
Definition: SYS_Types.h:115
GLuint GLuint end
Definition: glcorearb.h:474
GLfloat units
Definition: glcorearb.h:407
int int32
Definition: SYS_Types.h:34
void lock() const
int numJobs() const
void unlock() const
SYS_AtomicInt32 * myTask
int job() const