00001 /******************************************************************************* 00002 * 00003 * Copyright (c) 2000-2003 Intel Corporation 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * * Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * * Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * * Neither name of Intel Corporation nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 00022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00025 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00026 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00027 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 ******************************************************************************/ 00031 00032 00033 #ifndef THREADPOOL_H 00034 #define THREADPOOL_H 00035 00036 00042 #include "FreeList.h" 00043 #include "ithread.h" 00044 #include "LinkedList.h" 00045 #include "UpnpInet.h" 00046 #include "UpnpGlobal.h" /* for UPNP_INLINE, EXPORT_SPEC */ 00047 00048 00049 #include <errno.h> 00050 00051 00052 #ifdef WIN32 00053 #include <time.h> 00054 struct timezone 00055 { 00056 int tz_minuteswest; /* minutes W of Greenwich */ 00057 int tz_dsttime; /* type of dst correction */ 00058 }; 00059 int gettimeofday(struct timeval *tv, struct timezone *tz); 00060 #else /* WIN32 */ 00061 #include <sys/param.h> 00062 #include <sys/time.h> /* for gettimeofday() */ 00063 #if defined(__OSX__) || defined(__APPLE__) || defined(__NetBSD__) 00064 #include <sys/resource.h> /* for setpriority() */ 00065 #endif 00066 00067 #endif 00068 00069 00070 #ifdef __cplusplus 00071 extern "C" { 00072 #endif 00073 00074 00076 #define JOBFREELISTSIZE 100 00077 00078 00079 #define INFINITE_THREADS -1 00080 00081 00082 #define EMAXTHREADS (-8 & 1<<29) 00083 00084 00086 #define INVALID_POLICY (-9 & 1<<29) 00087 00088 00090 #define INVALID_JOB_ID (-2 & 1<<29) 00091 00092 00093 typedef enum duration { 00094 SHORT_TERM, 00095 PERSISTENT 00096 } Duration; 00097 00098 00099 typedef enum priority { 00100 LOW_PRIORITY, 00101 MED_PRIORITY, 00102 HIGH_PRIORITY 00103 } ThreadPriority; 00104 00105 00107 #define DEFAULT_PRIORITY MED_PRIORITY 00108 00109 00111 #define DEFAULT_MIN_THREADS 1 00112 00113 00115 #define DEFAULT_MAX_THREADS 10 00116 00117 00119 #define DEFAULT_JOBS_PER_THREAD 10 00120 00121 00123 #define DEFAULT_STARVATION_TIME 500 00124 00125 00127 #define DEFAULT_IDLE_TIME 10 * 1000 00128 00129 00131 #define DEFAULT_FREE_ROUTINE NULL 00132 00133 00135 #define DEFAULT_MAX_JOBS_TOTAL 100 00136 00137 00143 #define STATS 1 00144 00145 00146 #ifdef _DEBUG 00147 #define DEBUG 1 00148 #endif 00149 00150 00151 typedef int PolicyType; 00152 00153 00154 #define DEFAULT_POLICY SCHED_OTHER 00155 00156 00158 #define DEFAULT_SCHED_PARAM 0 00159 00160 00161 /**************************************************************************** 00162 * Name: free_routine 00163 * 00164 * Description: 00165 * Function for freeing a thread argument 00166 *****************************************************************************/ 00167 typedef void (*free_routine)(void *arg); 00168 00169 00170 /**************************************************************************** 00171 * Name: ThreadPoolAttr 00172 * 00173 * Description: 00174 * Attributes for thread pool. Used to set and change parameters of 00175 * thread pool 00176 *****************************************************************************/ 00177 typedef struct THREADPOOLATTR 00178 { 00179 /* minThreads, ThreadPool will always maintain at least this many threads */ 00180 int minThreads; 00181 00182 /* maxThreads, ThreadPool will never have more than this number of threads */ 00183 int maxThreads; 00184 00185 /* maxIdleTime (in milliseconds) this is the maximum time a thread will 00186 * remain idle before dying */ 00187 int maxIdleTime; 00188 00189 /* jobs per thread to maintain */ 00190 int jobsPerThread; 00191 00192 /* maximum number of jobs that can be queued totally. */ 00193 int maxJobsTotal; 00194 00195 /* the time a low priority or med priority job waits before getting bumped 00196 * up a priority (in milliseconds) */ 00197 int starvationTime; 00198 00199 /* scheduling policy to use */ 00200 PolicyType schedPolicy; 00201 } ThreadPoolAttr; 00202 00203 00204 /**************************************************************************** 00205 * Name: ThreadPool 00206 * 00207 * Description: 00208 * Internal ThreadPool Job 00209 *****************************************************************************/ 00210 typedef struct THREADPOOLJOB 00211 { 00212 start_routine func; 00213 void *arg; 00214 free_routine free_func; 00215 struct timeval requestTime; 00216 int priority; 00217 int jobId; 00218 } ThreadPoolJob; 00219 00220 00221 /**************************************************************************** 00222 * Name: ThreadPoolStats 00223 * 00224 * Description: 00225 * Structure to hold statistics 00226 *****************************************************************************/ 00227 typedef struct TPOOLSTATS 00228 { 00229 double totalTimeHQ; 00230 int totalJobsHQ; 00231 double avgWaitHQ; 00232 double totalTimeMQ; 00233 int totalJobsMQ; 00234 double avgWaitMQ; 00235 double totalTimeLQ; 00236 int totalJobsLQ; 00237 double avgWaitLQ; 00238 double totalWorkTime; 00239 double totalIdleTime; 00240 int workerThreads; 00241 int idleThreads; 00242 int persistentThreads; 00243 int totalThreads; 00244 int maxThreads; 00245 int currentJobsHQ; 00246 int currentJobsLQ; 00247 int currentJobsMQ; 00248 } ThreadPoolStats; 00249 00250 00266 typedef struct THREADPOOL 00267 { 00268 ithread_mutex_t mutex; /* mutex to protect job qs */ 00269 ithread_cond_t condition; /* condition variable to signal Q */ 00270 ithread_cond_t start_and_shutdown; /* condition variable for start and stop */ 00271 int lastJobId; /* ids for jobs */ 00272 int shutdown; /* whether or not we are shutting down */ 00273 int totalThreads; /* total number of threads */ 00274 int busyThreads; /* number of threads that are currently executing jobs */ 00275 int persistentThreads; /* number of persistent threads */ 00276 FreeList jobFreeList; /* free list of jobs */ 00277 LinkedList lowJobQ; /* low priority job Q */ 00278 LinkedList medJobQ; /* med priority job Q */ 00279 LinkedList highJobQ; /* high priority job Q */ 00280 ThreadPoolJob *persistentJob; /* persistent job */ 00281 ThreadPoolAttr attr; /* thread pool attributes */ 00282 00283 /* statistics */ 00284 ThreadPoolStats stats; 00285 } ThreadPool; 00286 00287 00288 /**************************************************************************** 00289 * Function: ThreadPoolInit 00290 * 00291 * Description: 00292 * Initializes and starts ThreadPool. Must be called first. 00293 * And only once for ThreadPool. 00294 * Parameters: 00295 * tp - must be valid, non null, pointer to ThreadPool. 00296 * attr - can be null 00297 * 00298 * if not null then attr contains the following fields: 00299 * 00300 * minWorkerThreads - minimum number of worker threads 00301 * thread pool will never have less than this 00302 * number of threads. 00303 * maxWorkerThreads - maximum number of worker threads 00304 * thread pool will never have more than this 00305 * number of threads. 00306 * maxIdleTime - maximum time that a worker thread will spend 00307 * idle. If a worker is idle longer than this 00308 * time and there are more than the min 00309 * number of workers running, than the 00310 * worker thread exits. 00311 * jobsPerThread - ratio of jobs to thread to try and maintain 00312 * if a job is scheduled and the number of jobs per 00313 * thread is greater than this number,and 00314 * if less than the maximum number of 00315 * workers are running then a new thread is 00316 * started to help out with efficiency. 00317 * schedPolicy - scheduling policy to try and set (OS dependent) 00318 * Returns: 00319 * 0 on success, nonzero on failure. 00320 * EAGAIN if not enough system resources to create minimum threads. 00321 * INVALID_POLICY if schedPolicy can't be set 00322 * EMAXTHREADS if minimum threads is greater than maximum threads 00323 *****************************************************************************/ 00324 int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr); 00325 00326 00327 /**************************************************************************** 00328 * Function: ThreadPoolAddPersistent 00329 * 00330 * Description: 00331 * Adds a persistent job to the thread pool. 00332 * Job will be run as soon as possible. 00333 * Call will block until job is scheduled. 00334 * Parameters: 00335 * tp - valid thread pool pointer 00336 * ThreadPoolJob - valid thread pool job with the following fields: 00337 * 00338 * func - ThreadFunction to run 00339 * arg - argument to function. 00340 * priority - priority of job. 00341 * 00342 * Returns: 00343 * 0 on success, nonzero on failure 00344 * EOUTOFMEM not enough memory to add job. 00345 * EMAXTHREADS not enough threads to add persistent job. 00346 *****************************************************************************/ 00347 int ThreadPoolAddPersistent(ThreadPool*tp, ThreadPoolJob *job, int *jobId); 00348 00349 00350 /**************************************************************************** 00351 * Function: ThreadPoolGetAttr 00352 * 00353 * Description: 00354 * Gets the current set of attributes 00355 * associated with the thread pool. 00356 * Parameters: 00357 * tp - valid thread pool pointer 00358 * out - non null pointer to store attributes 00359 * Returns: 00360 * 0 on success, nonzero on failure 00361 * Always returns 0. 00362 *****************************************************************************/ 00363 int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out); 00364 00365 00366 /**************************************************************************** 00367 * Function: ThreadPoolSetAttr 00368 * 00369 * Description: 00370 * Sets the attributes for the thread pool. 00371 * Only affects future calculations. 00372 * Parameters: 00373 * tp - valid thread pool pointer 00374 * attr - pointer to attributes, null sets attributes to default. 00375 * Returns: 00376 * 0 on success, nonzero on failure 00377 * Returns INVALID_POLICY if policy can not be set. 00378 *****************************************************************************/ 00379 int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr); 00380 00381 00382 /**************************************************************************** 00383 * Function: ThreadPoolAdd 00384 * 00385 * Description: 00386 * Adds a job to the thread pool. 00387 * Job will be run as soon as possible. 00388 * Parameters: 00389 * tp - valid thread pool pointer 00390 * func - ThreadFunction to run 00391 * arg - argument to function. 00392 * priority - priority of job. 00393 * poolid - id of job 00394 * free_function - function to use when freeing argument 00395 * Returns: 00396 * 0 on success, nonzero on failure 00397 * EOUTOFMEM if not enough memory to add job. 00398 *****************************************************************************/ 00399 int ThreadPoolAdd (ThreadPool*tp, ThreadPoolJob *job, int *jobId); 00400 00401 00402 /**************************************************************************** 00403 * Function: ThreadPoolRemove 00404 * 00405 * Description: 00406 * Removes a job from the thread pool. 00407 * Can only remove jobs which are not 00408 * currently running. 00409 * Parameters: 00410 * tp - valid thread pool pointer 00411 * jobid - id of job 00412 * out - space for removed job. 00413 * Returns: 00414 * 0 on success, nonzero on failure. 00415 * INVALID_JOB_ID if job not found. 00416 *****************************************************************************/ 00417 int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out); 00418 00419 00420 00421 /**************************************************************************** 00422 * Function: ThreadPoolShutdown 00423 * 00424 * Description: 00425 * Shuts the thread pool down. 00426 * Waits for all threads to finish. 00427 * May block indefinitely if jobs do not 00428 * exit. 00429 * Parameters: 00430 * tp - must be valid tp 00431 * Returns: 00432 * 0 on success, nonzero on failure 00433 * Always returns 0. 00434 *****************************************************************************/ 00435 int ThreadPoolShutdown(ThreadPool *tp); 00436 00437 00438 /**************************************************************************** 00439 * Function: TPJobInit 00440 * 00441 * Description: 00442 * Initializes thread pool job. 00443 * Sets the priority to default defined in ThreadPool.h. 00444 * Sets the free_routine to default defined in ThreadPool.h 00445 * Parameters: 00446 * ThreadPoolJob *job - must be valid thread pool attributes. 00447 * start_routine func - function to run, must be valid 00448 * void * arg - argument to pass to function. 00449 * Returns: 00450 * Always returns 0. 00451 *****************************************************************************/ 00452 int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg); 00453 00454 00455 /**************************************************************************** 00456 * Function: TPJobSetPriority 00457 * 00458 * Description: 00459 * Sets the max threads for the thread pool attributes. 00460 * Parameters: 00461 * attr - must be valid thread pool attributes. 00462 * maxThreads - value to set 00463 * Returns: 00464 * Always returns 0. 00465 *****************************************************************************/ 00466 int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority); 00467 00468 00469 /**************************************************************************** 00470 * Function: TPJobSetFreeFunction 00471 * 00472 * Description: 00473 * Sets the max threads for the thread pool attributes. 00474 * Parameters: 00475 * attr - must be valid thread pool attributes. 00476 * maxThreads - value to set 00477 * Returns: 00478 * Always returns 0. 00479 *****************************************************************************/ 00480 int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func); 00481 00482 00483 /**************************************************************************** 00484 * Function: TPAttrInit 00485 * 00486 * Description: 00487 * Initializes thread pool attributes. 00488 * Sets values to defaults defined in ThreadPool.h. 00489 * Parameters: 00490 * attr - must be valid thread pool attributes. 00491 * Returns: 00492 * Always returns 0. 00493 *****************************************************************************/ 00494 int TPAttrInit(ThreadPoolAttr *attr); 00495 00496 00497 /**************************************************************************** 00498 * Function: TPAttrSetMaxThreads 00499 * 00500 * Description: 00501 * Sets the max threads for the thread pool attributes. 00502 * Parameters: 00503 * attr - must be valid thread pool attributes. 00504 * maxThreads - value to set 00505 * Returns: 00506 * Always returns 0. 00507 *****************************************************************************/ 00508 int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads); 00509 00510 00511 /**************************************************************************** 00512 * Function: TPAttrSetMinThreads 00513 * 00514 * Description: 00515 * Sets the min threads for the thread pool attributes. 00516 * Parameters: 00517 * attr - must be valid thread pool attributes. 00518 * minThreads - value to set 00519 * Returns: 00520 * Always returns 0. 00521 *****************************************************************************/ 00522 int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads); 00523 00524 00525 /**************************************************************************** 00526 * Function: TPAttrSetIdleTime 00527 * 00528 * Description: 00529 * Sets the idle time for the thread pool attributes. 00530 * Parameters: 00531 * attr - must be valid thread pool attributes. 00532 * Returns: 00533 * Always returns 0. 00534 *****************************************************************************/ 00535 int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime); 00536 00537 00538 /**************************************************************************** 00539 * Function: TPAttrSetJobsPerThread 00540 * 00541 * Description: 00542 * Sets the jobs per thread ratio 00543 * Parameters: 00544 * attr - must be valid thread pool attributes. 00545 * jobsPerThread - number of jobs per thread to maintain 00546 * Returns: 00547 * Always returns 0. 00548 *****************************************************************************/ 00549 int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread); 00550 00551 00552 /**************************************************************************** 00553 * Function: TPAttrSetStarvationTime 00554 * 00555 * Description: 00556 * Sets the starvation time for the thread pool attributes. 00557 * Parameters: 00558 * attr - must be valid thread pool attributes. 00559 * int starvationTime - milliseconds 00560 * Returns: 00561 * Always returns 0. 00562 *****************************************************************************/ 00563 int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime); 00564 00565 00566 /**************************************************************************** 00567 * Function: TPAttrSetSchedPolicy 00568 * 00569 * Description: 00570 * Sets the scheduling policy for the thread pool attributes. 00571 * Parameters: 00572 * attr - must be valid thread pool attributes. 00573 * PolicyType schedPolicy - must be a valid policy type. 00574 * Returns: 00575 * Always returns 0. 00576 *****************************************************************************/ 00577 int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy); 00578 00579 00580 /**************************************************************************** 00581 * Function: TPAttrSetMaxJobsTotal 00582 * 00583 * Description: 00584 * Sets the maximum number jobs that can be qeued totally. 00585 * Parameters: 00586 * attr - must be valid thread pool attributes. 00587 * maxJobsTotal - maximum number of jobs 00588 * Returns: 00589 * Always returns 0. 00590 *****************************************************************************/ 00591 int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal); 00592 00593 00594 /**************************************************************************** 00595 * Function: ThreadPoolGetStats 00596 * 00597 * Description: 00598 * Returns various statistics about the 00599 * thread pool. 00600 * Only valid if STATS has been defined. 00601 * Parameters: 00602 * ThreadPool *tp - valid initialized threadpool 00603 * ThreadPoolStats *stats - valid stats, out parameter 00604 * Returns: 00605 * Always returns 0. 00606 *****************************************************************************/ 00607 #ifdef STATS 00608 EXPORT_SPEC int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats); 00609 00610 EXPORT_SPEC void ThreadPoolPrintStats(ThreadPoolStats *stats); 00611 #else 00612 static UPNP_INLINE int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats) {} 00613 00614 static UPNP_INLINE void ThreadPoolPrintStats(ThreadPoolStats *stats) {} 00615 #endif 00616 00617 00618 #ifdef __cplusplus 00619 } 00620 #endif 00621 00622 00623 #endif /* THREADPOOL_H */ 00624