/******************************************************************************* * * Copyright (c) 2000-2003 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither name of Intel Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************/ #ifndef THREADPOOL_H #define THREADPOOL_H /*! * \file */ #include "FreeList.h" #include "ithread.h" #include "LinkedList.h" #include "UpnpInet.h" #include "UpnpGlobal.h" /* for UPNP_INLINE, EXPORT_SPEC */ #include #ifdef WIN32 #include struct timezone { int tz_minuteswest; /* minutes W of Greenwich */ int tz_dsttime; /* type of dst correction */ }; int gettimeofday(struct timeval *tv, struct timezone *tz); #else /* WIN32 */ #include #include /* for gettimeofday() */ #if defined(__OSX__) || defined(__APPLE__) || defined(__NetBSD__) #include /* for setpriority() */ #endif #endif #ifdef __cplusplus extern "C" { #endif /*! Size of job free list */ #define JOBFREELISTSIZE 100 #define INFINITE_THREADS -1 #define EMAXTHREADS (-8 & 1<<29) /*! Invalid Policy */ #define INVALID_POLICY (-9 & 1<<29) /*! Invalid JOB Id */ #define INVALID_JOB_ID (-2 & 1<<29) typedef enum duration { SHORT_TERM, PERSISTENT } Duration; typedef enum priority { LOW_PRIORITY, MED_PRIORITY, HIGH_PRIORITY } ThreadPriority; /*! default priority used by TPJobInit */ #define DEFAULT_PRIORITY MED_PRIORITY /*! default minimum used by TPAttrInit */ #define DEFAULT_MIN_THREADS 1 /*! default max used by TPAttrInit */ #define DEFAULT_MAX_THREADS 10 /*! default jobs per thread used by TPAttrInit */ #define DEFAULT_JOBS_PER_THREAD 10 /*! default starvation time used by TPAttrInit */ #define DEFAULT_STARVATION_TIME 500 /*! default idle time used by TPAttrInit */ #define DEFAULT_IDLE_TIME 10 * 1000 /*! default free routine used TPJobInit */ #define DEFAULT_FREE_ROUTINE NULL /*! default max jobs used TPAttrInit */ #define DEFAULT_MAX_JOBS_TOTAL 100 /*! * \brief Statistics. * * Always include stats because code change is minimal. */ #define STATS 1 #ifdef _DEBUG #define DEBUG 1 #endif typedef int PolicyType; #define DEFAULT_POLICY SCHED_OTHER /*! Default priority */ #define DEFAULT_SCHED_PARAM 0 /**************************************************************************** * Name: free_routine * * Description: * Function for freeing a thread argument *****************************************************************************/ typedef void (*free_routine)(void *arg); /**************************************************************************** * Name: ThreadPoolAttr * * Description: * Attributes for thread pool. Used to set and change parameters of * thread pool *****************************************************************************/ typedef struct THREADPOOLATTR { /* minThreads, ThreadPool will always maintain at least this many threads */ int minThreads; /* maxThreads, ThreadPool will never have more than this number of threads */ int maxThreads; /* maxIdleTime (in milliseconds) this is the maximum time a thread will * remain idle before dying */ int maxIdleTime; /* jobs per thread to maintain */ int jobsPerThread; /* maximum number of jobs that can be queued totally. */ int maxJobsTotal; /* the time a low priority or med priority job waits before getting bumped * up a priority (in milliseconds) */ int starvationTime; /* scheduling policy to use */ PolicyType schedPolicy; } ThreadPoolAttr; /**************************************************************************** * Name: ThreadPool * * Description: * Internal ThreadPool Job *****************************************************************************/ typedef struct THREADPOOLJOB { start_routine func; void *arg; free_routine free_func; struct timeval requestTime; int priority; int jobId; } ThreadPoolJob; /**************************************************************************** * Name: ThreadPoolStats * * Description: * Structure to hold statistics *****************************************************************************/ typedef struct TPOOLSTATS { double totalTimeHQ; int totalJobsHQ; double avgWaitHQ; double totalTimeMQ; int totalJobsMQ; double avgWaitMQ; double totalTimeLQ; int totalJobsLQ; double avgWaitLQ; double totalWorkTime; double totalIdleTime; int workerThreads; int idleThreads; int persistentThreads; int totalThreads; int maxThreads; int currentJobsHQ; int currentJobsLQ; int currentJobsMQ; } ThreadPoolStats; /*! * \brief A thread pool similar to the thread pool in the UPnP SDK. * * Allows jobs to be scheduled for running by threads in a * thread pool. The thread pool is initialized with a * minimum and maximum thread number as well as a max idle time * and a jobs per thread ratio. If a worker thread waits the whole * max idle time without receiving a job and the thread pool * currently has more threads running than the minimum * then the worker thread will exit. If when * scheduling a job the current job to thread ratio * becomes greater than the set ratio and the thread pool currently has * less than the maximum threads then a new thread will * be created. */ typedef struct THREADPOOL { ithread_mutex_t mutex; /* mutex to protect job qs */ ithread_cond_t condition; /* condition variable to signal Q */ ithread_cond_t start_and_shutdown; /* condition variable for start and stop */ int lastJobId; /* ids for jobs */ int shutdown; /* whether or not we are shutting down */ int totalThreads; /* total number of threads */ int busyThreads; /* number of threads that are currently executing jobs */ int persistentThreads; /* number of persistent threads */ FreeList jobFreeList; /* free list of jobs */ LinkedList lowJobQ; /* low priority job Q */ LinkedList medJobQ; /* med priority job Q */ LinkedList highJobQ; /* high priority job Q */ ThreadPoolJob *persistentJob; /* persistent job */ ThreadPoolAttr attr; /* thread pool attributes */ /* statistics */ ThreadPoolStats stats; } ThreadPool; /**************************************************************************** * Function: ThreadPoolInit * * Description: * Initializes and starts ThreadPool. Must be called first. * And only once for ThreadPool. * Parameters: * tp - must be valid, non null, pointer to ThreadPool. * attr - can be null * * if not null then attr contains the following fields: * * minWorkerThreads - minimum number of worker threads * thread pool will never have less than this * number of threads. * maxWorkerThreads - maximum number of worker threads * thread pool will never have more than this * number of threads. * maxIdleTime - maximum time that a worker thread will spend * idle. If a worker is idle longer than this * time and there are more than the min * number of workers running, than the * worker thread exits. * jobsPerThread - ratio of jobs to thread to try and maintain * if a job is scheduled and the number of jobs per * thread is greater than this number,and * if less than the maximum number of * workers are running then a new thread is * started to help out with efficiency. * schedPolicy - scheduling policy to try and set (OS dependent) * Returns: * 0 on success, nonzero on failure. * EAGAIN if not enough system resources to create minimum threads. * INVALID_POLICY if schedPolicy can't be set * EMAXTHREADS if minimum threads is greater than maximum threads *****************************************************************************/ int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr); /**************************************************************************** * Function: ThreadPoolAddPersistent * * Description: * Adds a persistent job to the thread pool. * Job will be run as soon as possible. * Call will block until job is scheduled. * Parameters: * tp - valid thread pool pointer * ThreadPoolJob - valid thread pool job with the following fields: * * func - ThreadFunction to run * arg - argument to function. * priority - priority of job. * * Returns: * 0 on success, nonzero on failure * EOUTOFMEM not enough memory to add job. * EMAXTHREADS not enough threads to add persistent job. *****************************************************************************/ int ThreadPoolAddPersistent(ThreadPool*tp, ThreadPoolJob *job, int *jobId); /**************************************************************************** * Function: ThreadPoolGetAttr * * Description: * Gets the current set of attributes * associated with the thread pool. * Parameters: * tp - valid thread pool pointer * out - non null pointer to store attributes * Returns: * 0 on success, nonzero on failure * Always returns 0. *****************************************************************************/ int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out); /**************************************************************************** * Function: ThreadPoolSetAttr * * Description: * Sets the attributes for the thread pool. * Only affects future calculations. * Parameters: * tp - valid thread pool pointer * attr - pointer to attributes, null sets attributes to default. * Returns: * 0 on success, nonzero on failure * Returns INVALID_POLICY if policy can not be set. *****************************************************************************/ int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr); /**************************************************************************** * Function: ThreadPoolAdd * * Description: * Adds a job to the thread pool. * Job will be run as soon as possible. * Parameters: * tp - valid thread pool pointer * func - ThreadFunction to run * arg - argument to function. * priority - priority of job. * poolid - id of job * free_function - function to use when freeing argument * Returns: * 0 on success, nonzero on failure * EOUTOFMEM if not enough memory to add job. *****************************************************************************/ int ThreadPoolAdd (ThreadPool*tp, ThreadPoolJob *job, int *jobId); /**************************************************************************** * Function: ThreadPoolRemove * * Description: * Removes a job from the thread pool. * Can only remove jobs which are not * currently running. * Parameters: * tp - valid thread pool pointer * jobid - id of job * out - space for removed job. * Returns: * 0 on success, nonzero on failure. * INVALID_JOB_ID if job not found. *****************************************************************************/ int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out); /**************************************************************************** * Function: ThreadPoolShutdown * * Description: * Shuts the thread pool down. * Waits for all threads to finish. * May block indefinitely if jobs do not * exit. * Parameters: * tp - must be valid tp * Returns: * 0 on success, nonzero on failure * Always returns 0. *****************************************************************************/ int ThreadPoolShutdown(ThreadPool *tp); /**************************************************************************** * Function: TPJobInit * * Description: * Initializes thread pool job. * Sets the priority to default defined in ThreadPool.h. * Sets the free_routine to default defined in ThreadPool.h * Parameters: * ThreadPoolJob *job - must be valid thread pool attributes. * start_routine func - function to run, must be valid * void * arg - argument to pass to function. * Returns: * Always returns 0. *****************************************************************************/ int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg); /**************************************************************************** * Function: TPJobSetPriority * * Description: * Sets the max threads for the thread pool attributes. * Parameters: * attr - must be valid thread pool attributes. * maxThreads - value to set * Returns: * Always returns 0. *****************************************************************************/ int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority); /**************************************************************************** * Function: TPJobSetFreeFunction * * Description: * Sets the max threads for the thread pool attributes. * Parameters: * attr - must be valid thread pool attributes. * maxThreads - value to set * Returns: * Always returns 0. *****************************************************************************/ int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func); /**************************************************************************** * Function: TPAttrInit * * Description: * Initializes thread pool attributes. * Sets values to defaults defined in ThreadPool.h. * Parameters: * attr - must be valid thread pool attributes. * Returns: * Always returns 0. *****************************************************************************/ int TPAttrInit(ThreadPoolAttr *attr); /**************************************************************************** * Function: TPAttrSetMaxThreads * * Description: * Sets the max threads for the thread pool attributes. * Parameters: * attr - must be valid thread pool attributes. * maxThreads - value to set * Returns: * Always returns 0. *****************************************************************************/ int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads); /**************************************************************************** * Function: TPAttrSetMinThreads * * Description: * Sets the min threads for the thread pool attributes. * Parameters: * attr - must be valid thread pool attributes. * minThreads - value to set * Returns: * Always returns 0. *****************************************************************************/ int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads); /**************************************************************************** * Function: TPAttrSetIdleTime * * Description: * Sets the idle time for the thread pool attributes. * Parameters: * attr - must be valid thread pool attributes. * Returns: * Always returns 0. *****************************************************************************/ int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime); /**************************************************************************** * Function: TPAttrSetJobsPerThread * * Description: * Sets the jobs per thread ratio * Parameters: * attr - must be valid thread pool attributes. * jobsPerThread - number of jobs per thread to maintain * Returns: * Always returns 0. *****************************************************************************/ int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread); /**************************************************************************** * Function: TPAttrSetStarvationTime * * Description: * Sets the starvation time for the thread pool attributes. * Parameters: * attr - must be valid thread pool attributes. * int starvationTime - milliseconds * Returns: * Always returns 0. *****************************************************************************/ int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime); /**************************************************************************** * Function: TPAttrSetSchedPolicy * * Description: * Sets the scheduling policy for the thread pool attributes. * Parameters: * attr - must be valid thread pool attributes. * PolicyType schedPolicy - must be a valid policy type. * Returns: * Always returns 0. *****************************************************************************/ int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy); /**************************************************************************** * Function: TPAttrSetMaxJobsTotal * * Description: * Sets the maximum number jobs that can be qeued totally. * Parameters: * attr - must be valid thread pool attributes. * maxJobsTotal - maximum number of jobs * Returns: * Always returns 0. *****************************************************************************/ int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal); /**************************************************************************** * Function: ThreadPoolGetStats * * Description: * Returns various statistics about the * thread pool. * Only valid if STATS has been defined. * Parameters: * ThreadPool *tp - valid initialized threadpool * ThreadPoolStats *stats - valid stats, out parameter * Returns: * Always returns 0. *****************************************************************************/ #ifdef STATS EXPORT_SPEC int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats); EXPORT_SPEC void ThreadPoolPrintStats(ThreadPoolStats *stats); #else static UPNP_INLINE int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats) {} static UPNP_INLINE void ThreadPoolPrintStats(ThreadPoolStats *stats) {} #endif #ifdef __cplusplus } #endif #endif /* THREADPOOL_H */