libUPnP  1.8.0
ThreadPool.h
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * Copyright (c) 2000-2003 Intel Corporation
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  * * Neither name of Intel Corporation nor the names of its contributors
15  * may be used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  ******************************************************************************/
31 
32 
33 #ifndef THREADPOOL_H
34 #define THREADPOOL_H
35 
36 
42 #include "FreeList.h"
43 #include "ithread.h"
44 #include "LinkedList.h"
45 #include "UpnpInet.h"
46 #include "UpnpGlobal.h" /* for UPNP_INLINE, EXPORT_SPEC */
47 
48 
49 #include <errno.h>
50 
51 
52 #ifdef WIN32
53  #include <time.h>
54  struct timezone
55  {
56  int tz_minuteswest; /* minutes W of Greenwich */
57  int tz_dsttime; /* type of dst correction */
58  };
59  int gettimeofday(struct timeval *tv, struct timezone *tz);
60 #else /* WIN32 */
61  #include <sys/param.h>
62  #include <sys/time.h> /* for gettimeofday() */
63  #if defined(__OSX__) || defined(__APPLE__) || defined(__NetBSD__)
64  #include <sys/resource.h> /* for setpriority() */
65  #endif
66 
67 #endif
68 
69 
70 #ifdef __cplusplus
71 extern "C" {
72 #endif
73 
74 
76 #define JOBFREELISTSIZE 100
77 
78 
79 #define INFINITE_THREADS -1
80 
81 
82 #define EMAXTHREADS (-8 & 1<<29)
83 
84 
86 #define INVALID_POLICY (-9 & 1<<29)
87 
88 
90 #define INVALID_JOB_ID (-2 & 1<<29)
91 
92 
93 typedef enum duration {
94  SHORT_TERM,
95  PERSISTENT
96 } Duration;
97 
98 
99 typedef enum priority {
100  LOW_PRIORITY,
101  MED_PRIORITY,
102  HIGH_PRIORITY
103 } ThreadPriority;
104 
105 
107 #define DEFAULT_PRIORITY MED_PRIORITY
108 
109 
111 #define DEFAULT_MIN_THREADS 1
112 
113 
115 #define DEFAULT_MAX_THREADS 10
116 
117 
119 #define DEFAULT_JOBS_PER_THREAD 10
120 
121 
123 #define DEFAULT_STARVATION_TIME 500
124 
125 
127 #define DEFAULT_IDLE_TIME 10 * 1000
128 
129 
131 #define DEFAULT_FREE_ROUTINE NULL
132 
133 
135 #define DEFAULT_MAX_JOBS_TOTAL 100
136 
137 
143 #define STATS 1
144 
145 
146 #ifdef _DEBUG
147  #define DEBUG 1
148 #endif
149 
150 
151 typedef int PolicyType;
152 
153 
154 #define DEFAULT_POLICY SCHED_OTHER
155 
156 
158 #define DEFAULT_SCHED_PARAM 0
159 
160 
161 /****************************************************************************
162  * Name: free_routine
163  *
164  * Description:
165  * Function for freeing a thread argument
166  *****************************************************************************/
167 typedef void (*free_routine)(void *arg);
168 
169 
170 /****************************************************************************
171  * Name: ThreadPoolAttr
172  *
173  * Description:
174  * Attributes for thread pool. Used to set and change parameters of
175  * thread pool
176  *****************************************************************************/
177 typedef struct THREADPOOLATTR
178 {
179  /* minThreads, ThreadPool will always maintain at least this many threads */
180  int minThreads;
181 
182  /* maxThreads, ThreadPool will never have more than this number of threads */
183  int maxThreads;
184 
185  /* maxIdleTime (in milliseconds) this is the maximum time a thread will
186  * remain idle before dying */
187  int maxIdleTime;
188 
189  /* jobs per thread to maintain */
190  int jobsPerThread;
191 
192  /* maximum number of jobs that can be queued totally. */
193  int maxJobsTotal;
194 
195  /* the time a low priority or med priority job waits before getting bumped
196  * up a priority (in milliseconds) */
197  int starvationTime;
198 
199  /* scheduling policy to use */
200  PolicyType schedPolicy;
202 
203 
204 /****************************************************************************
205  * Name: ThreadPool
206  *
207  * Description:
208  * Internal ThreadPool Job
209  *****************************************************************************/
210 typedef struct THREADPOOLJOB
211 {
212  start_routine func;
213  void *arg;
214  free_routine free_func;
215  struct timeval requestTime;
216  int priority;
217  int jobId;
218 } ThreadPoolJob;
219 
220 
221 /****************************************************************************
222  * Name: ThreadPoolStats
223  *
224  * Description:
225  * Structure to hold statistics
226  *****************************************************************************/
227 typedef struct TPOOLSTATS
228 {
229  double totalTimeHQ;
230  int totalJobsHQ;
231  double avgWaitHQ;
232  double totalTimeMQ;
233  int totalJobsMQ;
234  double avgWaitMQ;
235  double totalTimeLQ;
236  int totalJobsLQ;
237  double avgWaitLQ;
238  double totalWorkTime;
239  double totalIdleTime;
240  int workerThreads;
241  int idleThreads;
242  int persistentThreads;
243  int totalThreads;
244  int maxThreads;
245  int currentJobsHQ;
246  int currentJobsLQ;
247  int currentJobsMQ;
249 
250 
266 typedef struct THREADPOOL
267 {
268  ithread_mutex_t mutex; /* mutex to protect job qs */
269  ithread_cond_t condition; /* condition variable to signal Q */
270  ithread_cond_t start_and_shutdown; /* condition variable for start and stop */
271  int lastJobId; /* ids for jobs */
272  int shutdown; /* whether or not we are shutting down */
273  int totalThreads; /* total number of threads */
274  int busyThreads; /* number of threads that are currently executing jobs */
275  int persistentThreads; /* number of persistent threads */
276  FreeList jobFreeList; /* free list of jobs */
277  LinkedList lowJobQ; /* low priority job Q */
278  LinkedList medJobQ; /* med priority job Q */
279  LinkedList highJobQ; /* high priority job Q */
280  ThreadPoolJob *persistentJob; /* persistent job */
281  ThreadPoolAttr attr; /* thread pool attributes */
282 
283  /* statistics */
284  ThreadPoolStats stats;
285 } ThreadPool;
286 
287 
288 /****************************************************************************
289  * Function: ThreadPoolInit
290  *
291  * Description:
292  * Initializes and starts ThreadPool. Must be called first.
293  * And only once for ThreadPool.
294  * Parameters:
295  * tp - must be valid, non null, pointer to ThreadPool.
296  * attr - can be null
297  *
298  * if not null then attr contains the following fields:
299  *
300  * minWorkerThreads - minimum number of worker threads
301  * thread pool will never have less than this
302  * number of threads.
303  * maxWorkerThreads - maximum number of worker threads
304  * thread pool will never have more than this
305  * number of threads.
306  * maxIdleTime - maximum time that a worker thread will spend
307  * idle. If a worker is idle longer than this
308  * time and there are more than the min
309  * number of workers running, than the
310  * worker thread exits.
311  * jobsPerThread - ratio of jobs to thread to try and maintain
312  * if a job is scheduled and the number of jobs per
313  * thread is greater than this number,and
314  * if less than the maximum number of
315  * workers are running then a new thread is
316  * started to help out with efficiency.
317  * schedPolicy - scheduling policy to try and set (OS dependent)
318  * Returns:
319  * 0 on success, nonzero on failure.
320  * EAGAIN if not enough system resources to create minimum threads.
321  * INVALID_POLICY if schedPolicy can't be set
322  * EMAXTHREADS if minimum threads is greater than maximum threads
323  *****************************************************************************/
324 int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr);
325 
326 
327 /****************************************************************************
328  * Function: ThreadPoolAddPersistent
329  *
330  * Description:
331  * Adds a persistent job to the thread pool.
332  * Job will be run as soon as possible.
333  * Call will block until job is scheduled.
334  * Parameters:
335  * tp - valid thread pool pointer
336  * ThreadPoolJob - valid thread pool job with the following fields:
337  *
338  * func - ThreadFunction to run
339  * arg - argument to function.
340  * priority - priority of job.
341  *
342  * Returns:
343  * 0 on success, nonzero on failure
344  * EOUTOFMEM not enough memory to add job.
345  * EMAXTHREADS not enough threads to add persistent job.
346  *****************************************************************************/
347 int ThreadPoolAddPersistent(ThreadPool*tp, ThreadPoolJob *job, int *jobId);
348 
349 
350 /****************************************************************************
351  * Function: ThreadPoolGetAttr
352  *
353  * Description:
354  * Gets the current set of attributes
355  * associated with the thread pool.
356  * Parameters:
357  * tp - valid thread pool pointer
358  * out - non null pointer to store attributes
359  * Returns:
360  * 0 on success, nonzero on failure
361  * Always returns 0.
362  *****************************************************************************/
363 int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out);
364 
365 
366 /****************************************************************************
367  * Function: ThreadPoolSetAttr
368  *
369  * Description:
370  * Sets the attributes for the thread pool.
371  * Only affects future calculations.
372  * Parameters:
373  * tp - valid thread pool pointer
374  * attr - pointer to attributes, null sets attributes to default.
375  * Returns:
376  * 0 on success, nonzero on failure
377  * Returns INVALID_POLICY if policy can not be set.
378  *****************************************************************************/
379 int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr);
380 
381 
382 /****************************************************************************
383  * Function: ThreadPoolAdd
384  *
385  * Description:
386  * Adds a job to the thread pool.
387  * Job will be run as soon as possible.
388  * Parameters:
389  * tp - valid thread pool pointer
390  * func - ThreadFunction to run
391  * arg - argument to function.
392  * priority - priority of job.
393  * poolid - id of job
394  * free_function - function to use when freeing argument
395  * Returns:
396  * 0 on success, nonzero on failure
397  * EOUTOFMEM if not enough memory to add job.
398  *****************************************************************************/
399 int ThreadPoolAdd (ThreadPool*tp, ThreadPoolJob *job, int *jobId);
400 
401 
402 /****************************************************************************
403  * Function: ThreadPoolRemove
404  *
405  * Description:
406  * Removes a job from the thread pool.
407  * Can only remove jobs which are not
408  * currently running.
409  * Parameters:
410  * tp - valid thread pool pointer
411  * jobid - id of job
412  * out - space for removed job.
413  * Returns:
414  * 0 on success, nonzero on failure.
415  * INVALID_JOB_ID if job not found.
416  *****************************************************************************/
417 int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out);
418 
419 
420 
421 /****************************************************************************
422  * Function: ThreadPoolShutdown
423  *
424  * Description:
425  * Shuts the thread pool down.
426  * Waits for all threads to finish.
427  * May block indefinitely if jobs do not
428  * exit.
429  * Parameters:
430  * tp - must be valid tp
431  * Returns:
432  * 0 on success, nonzero on failure
433  * Always returns 0.
434  *****************************************************************************/
435 int ThreadPoolShutdown(ThreadPool *tp);
436 
437 
438 /****************************************************************************
439  * Function: TPJobInit
440  *
441  * Description:
442  * Initializes thread pool job.
443  * Sets the priority to default defined in ThreadPool.h.
444  * Sets the free_routine to default defined in ThreadPool.h
445  * Parameters:
446  * ThreadPoolJob *job - must be valid thread pool attributes.
447  * start_routine func - function to run, must be valid
448  * void * arg - argument to pass to function.
449  * Returns:
450  * Always returns 0.
451  *****************************************************************************/
452 int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg);
453 
454 
455 /****************************************************************************
456  * Function: TPJobSetPriority
457  *
458  * Description:
459  * Sets the max threads for the thread pool attributes.
460  * Parameters:
461  * attr - must be valid thread pool attributes.
462  * maxThreads - value to set
463  * Returns:
464  * Always returns 0.
465  *****************************************************************************/
466 int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority);
467 
468 
469 /****************************************************************************
470  * Function: TPJobSetFreeFunction
471  *
472  * Description:
473  * Sets the max threads for the thread pool attributes.
474  * Parameters:
475  * attr - must be valid thread pool attributes.
476  * maxThreads - value to set
477  * Returns:
478  * Always returns 0.
479  *****************************************************************************/
480 int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func);
481 
482 
483 /****************************************************************************
484  * Function: TPAttrInit
485  *
486  * Description:
487  * Initializes thread pool attributes.
488  * Sets values to defaults defined in ThreadPool.h.
489  * Parameters:
490  * attr - must be valid thread pool attributes.
491  * Returns:
492  * Always returns 0.
493  *****************************************************************************/
494 int TPAttrInit(ThreadPoolAttr *attr);
495 
496 
497 /****************************************************************************
498  * Function: TPAttrSetMaxThreads
499  *
500  * Description:
501  * Sets the max threads for the thread pool attributes.
502  * Parameters:
503  * attr - must be valid thread pool attributes.
504  * maxThreads - value to set
505  * Returns:
506  * Always returns 0.
507  *****************************************************************************/
508 int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads);
509 
510 
511 /****************************************************************************
512  * Function: TPAttrSetMinThreads
513  *
514  * Description:
515  * Sets the min threads for the thread pool attributes.
516  * Parameters:
517  * attr - must be valid thread pool attributes.
518  * minThreads - value to set
519  * Returns:
520  * Always returns 0.
521  *****************************************************************************/
522 int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads);
523 
524 
525 /****************************************************************************
526  * Function: TPAttrSetIdleTime
527  *
528  * Description:
529  * Sets the idle time for the thread pool attributes.
530  * Parameters:
531  * attr - must be valid thread pool attributes.
532  * Returns:
533  * Always returns 0.
534  *****************************************************************************/
535 int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime);
536 
537 
538 /****************************************************************************
539  * Function: TPAttrSetJobsPerThread
540  *
541  * Description:
542  * Sets the jobs per thread ratio
543  * Parameters:
544  * attr - must be valid thread pool attributes.
545  * jobsPerThread - number of jobs per thread to maintain
546  * Returns:
547  * Always returns 0.
548  *****************************************************************************/
549 int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread);
550 
551 
552 /****************************************************************************
553  * Function: TPAttrSetStarvationTime
554  *
555  * Description:
556  * Sets the starvation time for the thread pool attributes.
557  * Parameters:
558  * attr - must be valid thread pool attributes.
559  * int starvationTime - milliseconds
560  * Returns:
561  * Always returns 0.
562  *****************************************************************************/
563 int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime);
564 
565 
566 /****************************************************************************
567  * Function: TPAttrSetSchedPolicy
568  *
569  * Description:
570  * Sets the scheduling policy for the thread pool attributes.
571  * Parameters:
572  * attr - must be valid thread pool attributes.
573  * PolicyType schedPolicy - must be a valid policy type.
574  * Returns:
575  * Always returns 0.
576  *****************************************************************************/
577 int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy);
578 
579 
580 /****************************************************************************
581  * Function: TPAttrSetMaxJobsTotal
582  *
583  * Description:
584  * Sets the maximum number jobs that can be qeued totally.
585  * Parameters:
586  * attr - must be valid thread pool attributes.
587  * maxJobsTotal - maximum number of jobs
588  * Returns:
589  * Always returns 0.
590  *****************************************************************************/
591 int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
592 
593 
594 /****************************************************************************
595  * Function: ThreadPoolGetStats
596  *
597  * Description:
598  * Returns various statistics about the
599  * thread pool.
600  * Only valid if STATS has been defined.
601  * Parameters:
602  * ThreadPool *tp - valid initialized threadpool
603  * ThreadPoolStats *stats - valid stats, out parameter
604  * Returns:
605  * Always returns 0.
606  *****************************************************************************/
607 #ifdef STATS
608  EXPORT_SPEC int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats);
609 
610  EXPORT_SPEC void ThreadPoolPrintStats(ThreadPoolStats *stats);
611 #else
612  static UPNP_INLINE int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats) {}
613 
614  static UPNP_INLINE void ThreadPoolPrintStats(ThreadPoolStats *stats) {}
615 #endif
616 
617 
618 #ifdef __cplusplus
619 }
620 #endif
621 
622 
623 #endif /* THREADPOOL_H */
624 
Definition: ThreadPool.h:177
Definition: ThreadPool.h:227
struct THREADPOOL ThreadPool
A thread pool similar to the thread pool in the UPnP SDK.
A thread pool similar to the thread pool in the UPnP SDK.
Definition: ThreadPool.h:266
Provides a platform independent way to include TCP/IP types and functions.
Definition: FreeList.h:73
Definition: ThreadPool.h:210
#define UPNP_INLINE
Declares an inline function.
Definition: UpnpGlobal.h:91
#define EXPORT_SPEC
Export functions on WIN32 DLLs.
Definition: UpnpGlobal.h:82
Definition: LinkedList.h:111
Defines constants that for some reason are not defined on some systems.