libupnp/threadutil/inc/ThreadPool.h

621 lines
19 KiB
C
Raw Normal View History

/*******************************************************************************
*
* 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 "UpnpGlobal.h" /* for UPNP_INLINE, EXPORT_SPEC */
#include <errno.h>
#ifdef WIN32
#include <time.h>
#include <winsock2.h>
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 <sys/time.h> /* for gettimeofday() */
#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 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 */