From 467f9987a135986419222da968562aab26a3e637 Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Sat, 18 Sep 2010 05:56:29 -0300 Subject: [PATCH] Customize the stack size of the threads used by pupnp through the new THREAD_STACK_SIZE variable This patch allows a user to customize the stack size of the threads used by pupnp through the new THREAD_STACK_SIZE variable. This is especially useful on embedded systems with limited memory where the user can set THREAD_STACK_SIZE to ITHREAD_STACK_MIN. However, as this modification can have side effects, I set 0 as the default value, so threads will continue to use the default stack size of the system (which varies greatly as stated in https://computing.llnl.gov/tutorials/pthreads/). --- ChangeLog | 14 +++++++++++ build/inc/config.h | 18 +++++++++++++ threadutil/inc/ThreadPool.h | 22 ++++++++++++++++ threadutil/inc/ithread.h | 50 +++++++++++++++++++++++++++++++++++-- threadutil/src/ThreadPool.c | 29 ++++++++++++++++++++- upnp/src/api/upnpapi.c | 1 + upnp/src/inc/config.h | 18 +++++++++++++ 7 files changed, 149 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index f12969a..10f026c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,20 @@ Version 1.6.7 ******************************************************************************* +2010-09-18 Fabrice Fontaine + + Customize the stack size of the threads used by pupnp through the new THREAD_STACK_SIZE variable + + This patch allows a user to customize the stack size of the threads used by + pupnp through the new THREAD_STACK_SIZE variable. This is especially useful + on embedded systems with limited memory where the user can set THREAD_STACK_SIZE + to ITHREAD_STACK_MIN. + + However, as this modification can have side effects, I set 0 as the default + value, so threads will continue to use the default stack size of the system + (which varies greatly as stated in + https://computing.llnl.gov/tutorials/pthreads/). + 2010-09-16 Fabrice Fontaine Broken IPv6. diff --git a/build/inc/config.h b/build/inc/config.h index 6897309..794a463 100644 --- a/build/inc/config.h +++ b/build/inc/config.h @@ -111,6 +111,24 @@ /* @} */ +/*! + * \name THREAD_STACK_SIZE + * + * The {\tt THREAD_STACK_SIZE} constant defines the minimum stack size (in + * bytes) allocated for the stack of each thread the thread pool inside the + * SDK will create. These threads are used for both callbacks into + * applications built on top of the library and also for making connections + * to other control points and devices. This value will not be used if it + * is lower than ITHREAD_STACK_MIN or greater than a system-imposed limit. + * This value can be used to lower memory overhead in embedded systems. + * The default value is 0 (so it is not used by default). + * + * @{ + */ +#define THREAD_STACK_SIZE 0 +/* @} */ + + /*! \name MAX_JOBS_TOTAL * * The {\tt MAX_JOBS_TOTAL} constant determines the maximum number of jobs diff --git a/threadutil/inc/ThreadPool.h b/threadutil/inc/ThreadPool.h index efabd91..c33e97c 100644 --- a/threadutil/inc/ThreadPool.h +++ b/threadutil/inc/ThreadPool.h @@ -115,6 +115,10 @@ typedef enum priority { #define DEFAULT_MAX_THREADS 10 +/*! default stack size used by TPAttrInit */ +#define DEFAULT_STACK_SIZE 0 + + /*! default jobs per thread used by TPAttrInit */ #define DEFAULT_JOBS_PER_THREAD 10 @@ -182,6 +186,10 @@ typedef struct THREADPOOLATTR /* maxThreads, ThreadPool will never have more than this number of threads */ int maxThreads; + /* stackSize (in bytes), this is the minimum stack size allocated for each + * thread */ + size_t stackSize; + /* maxIdleTime (in milliseconds) this is the maximum time a thread will * remain idle before dying */ int maxIdleTime; @@ -522,6 +530,20 @@ int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads); int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads); +/**************************************************************************** + * Function: TPAttrSetStackSize + * + * Description: + * Sets the stack size for the thread pool attributes. + * Parameters: + * attr - must be valid thread pool attributes. + * stackSize - value to set + * Returns: + * Always returns 0. + *****************************************************************************/ +int TPAttrSetStackSize(ThreadPoolAttr *attr, size_t stackSize); + + /**************************************************************************** * Function: TPAttrSetIdleTime * diff --git a/threadutil/inc/ithread.h b/threadutil/inc/ithread.h index 4cd8c9b..98e3b83 100644 --- a/threadutil/inc/ithread.h +++ b/threadutil/inc/ithread.h @@ -85,7 +85,10 @@ extern "C" { #define ITHREAD_CANCELED PTHREAD_CANCELED - + +#define ITHREAD_STACK_MIN PTHREAD_STACK_MIN + + /*************************************************************************** * Name: ithread_t * @@ -726,6 +729,49 @@ static UPNP_INLINE int ithread_cleanup_thread(void) { ***************************************************************************/ #define ithread_cond_destroy pthread_cond_destroy + /**************************************************************************** + * Function: ithread_attr_init + * + * Description: + * Initialises thread attribute object. + * Parameters: + * ithread_attr_t *attr (must be valid non NULL pointer to + * ithread_attr_t) + * Returns: + * 0 on success. Nonzero on failure. + * See man page for pthread_attr_init + ***************************************************************************/ +#define ithread_attr_init pthread_attr_init + + /**************************************************************************** + * Function: ithread_attr_destroy + * + * Description: + * Destroys thread attribute object. + * Parameters: + * ithread_attr_t *attr (must be valid non NULL pointer to + * ithread_attr_t) + * Returns: + * 0 on success. Nonzero on failure. + * See man page for pthread_attr_destroy + ***************************************************************************/ +#define ithread_attr_destroy pthread_attr_destroy + + /**************************************************************************** + * Function: ithread_attr_setstacksize + * + * Description: + * Sets stack size of a thread attribute object. + * Parameters: + * ithread_attr_t *attr (must be valid non NULL pointer to + * ithread_attr_t) + * size_t stacksize (value of stacksize must be greater than + * ITHREAD_STACK_MIN and lower than system-imposed limits + * Returns: + * 0 on success. Nonzero on failure. + * See man page for pthread_attr_setstacksize + ***************************************************************************/ +#define ithread_attr_setstacksize pthread_attr_setstacksize /**************************************************************************** * Function: ithread_create @@ -735,7 +781,7 @@ static UPNP_INLINE int ithread_cleanup_thread(void) { * and argument. * Parameters: * ithread_t * thread (must be valid non NULL pointer to pthread_t) - * ithread_attr_t *attr, IGNORED + * ithread_attr_t *attr * void * (start_routine) (void *arg) (start routine) * void * arg - argument. * Returns: diff --git a/threadutil/src/ThreadPool.c b/threadutil/src/ThreadPool.c index d44a39b..da8a91c 100644 --- a/threadutil/src/ThreadPool.c +++ b/threadutil/src/ThreadPool.c @@ -609,12 +609,16 @@ static int CreateWorker(ThreadPool *tp) ithread_t temp; int rc = 0; int currentThreads = tp->totalThreads + 1; + ithread_attr_t attr; if (tp->attr.maxThreads != INFINITE_THREADS && currentThreads > tp->attr.maxThreads) { return EMAXTHREADS; } - rc = ithread_create(&temp, NULL, WorkerThread, tp); + ithread_attr_init(&attr); + ithread_attr_setstacksize(&attr, tp->attr.stackSize); + rc = ithread_create(&temp, &attr, WorkerThread, tp); + ithread_attr_destroy(&attr); if (rc == 0) { rc = ithread_detach(temp); while (tp->totalThreads < currentThreads) { @@ -1174,6 +1178,7 @@ int TPAttrInit(ThreadPoolAttr *attr) attr->maxIdleTime = DEFAULT_IDLE_TIME; attr->maxThreads = DEFAULT_MAX_THREADS; attr->minThreads = DEFAULT_MIN_THREADS; + attr->stackSize = DEFAULT_STACK_SIZE; attr->schedPolicy = DEFAULT_POLICY; attr->starvationTime = DEFAULT_STARVATION_TIME; attr->maxJobsTotal = DEFAULT_MAX_JOBS_TOTAL; @@ -1298,6 +1303,28 @@ int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads) return 0; } +/**************************************************************************** + * Function: TPAttrSetStackSize + * + * Description: + * Sets the stack size for the thread pool attributes. + * Parameters: + * attr - must be valid thread pool attributes. + * stackSize - value to set + * Returns: + * Always returns 0. + *****************************************************************************/ +int TPAttrSetStackSize(ThreadPoolAttr *attr, size_t stackSize) +{ + if (!attr) { + return EINVAL; + } + attr->stackSize = stackSize; + + return 0; +} + + /**************************************************************************** * Function: TPAttrSetIdleTime * diff --git a/upnp/src/api/upnpapi.c b/upnp/src/api/upnpapi.c index 9463aca..0fc1f96 100644 --- a/upnp/src/api/upnpapi.c +++ b/upnp/src/api/upnpapi.c @@ -282,6 +282,7 @@ static int UpnpInitThreadPools(void) TPAttrInit(&attr); TPAttrSetMaxThreads(&attr, MAX_THREADS); TPAttrSetMinThreads(&attr, MIN_THREADS); + TPAttrSetStackSize(&attr, THREAD_STACK_SIZE); TPAttrSetJobsPerThread(&attr, JOBS_PER_THREAD); TPAttrSetIdleTime(&attr, THREAD_IDLE_TIME); TPAttrSetMaxJobsTotal(&attr, MAX_JOBS_TOTAL); diff --git a/upnp/src/inc/config.h b/upnp/src/inc/config.h index 6897309..794a463 100644 --- a/upnp/src/inc/config.h +++ b/upnp/src/inc/config.h @@ -111,6 +111,24 @@ /* @} */ +/*! + * \name THREAD_STACK_SIZE + * + * The {\tt THREAD_STACK_SIZE} constant defines the minimum stack size (in + * bytes) allocated for the stack of each thread the thread pool inside the + * SDK will create. These threads are used for both callbacks into + * applications built on top of the library and also for making connections + * to other control points and devices. This value will not be used if it + * is lower than ITHREAD_STACK_MIN or greater than a system-imposed limit. + * This value can be used to lower memory overhead in embedded systems. + * The default value is 0 (so it is not used by default). + * + * @{ + */ +#define THREAD_STACK_SIZE 0 +/* @} */ + + /*! \name MAX_JOBS_TOTAL * * The {\tt MAX_JOBS_TOTAL} constant determines the maximum number of jobs