* Added API to ithread, created the following functions:
- int ithread_initialize_library(void); - int ithread_cleanup_library(void); - int ithread_initialize_thread(void); - int ithread_cleanup_thread(void); * SF Bug Tracker [ 2876374 ] Access Violation when compiling with Visual Studio 2008 Submitted: Stulle ( stulleamgym ) - 2009-10-10 19:05 Hi, I am one of the devs of the MorphXT project and I use this lib in some other of my projects, too. When I tried to upgrade the lib earlier for one of my projects I had to realise that something did not work at first and while most of the things were reasonably ease to be fixed. Now, the last thing I encountered was not so easy to fix and I am uncertain if my fix is any good so I'll just post it here and wait for some comments. The problem was that I got an Access Violation when calling "UpnpInit". It would call "ithread_rwlock_init(&GlobalHndRWLock, NULL)" which eventually led to calling "pthread_cond_init" and I got the error notice at "EnterCriticalSection (&ptw32_cond_list_lock);". It appeared that "ptw32_cond_list_lock" was NULL. Now, I found two ways to fix this. Firstly moving the whole block after at least one of the "ThreadPoolInit" calls will fix the issue. Secondly, you could add: #ifdef WIN32 #ifdef PTW32_STATIC_LIB // to get the following working we need this... is it a good patch or not... I do not know! pthread_win32_process_attach_np(); #endif #endif right before "ithread_rwlock_init(&GlobalHndRWLock, NULL)". Just so you know, I am using libupnp 1.6.6 and libpthreads 2.8.0 and both are linked static into the binaries. I am currently using Visual Studio 2008 for development with Windows being the target OS. Any comment at your end? Regards, Stulle git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@527 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
parent
9c440e2cbf
commit
3fb182aa95
43
ChangeLog
43
ChangeLog
@ -2,7 +2,48 @@
|
|||||||
Version 1.8.0
|
Version 1.8.0
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
|
|
||||||
2010-03-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||||
|
* Added API to ithread, created the following functions:
|
||||||
|
- int ithread_initialize_library(void);
|
||||||
|
- int ithread_cleanup_library(void);
|
||||||
|
- int ithread_initialize_thread(void);
|
||||||
|
- int ithread_cleanup_thread(void);
|
||||||
|
* SF Bug Tracker [ 2876374 ] Access Violation when compiling with Visual Studio 2008
|
||||||
|
Submitted: Stulle ( stulleamgym ) - 2009-10-10 19:05
|
||||||
|
|
||||||
|
Hi,
|
||||||
|
|
||||||
|
I am one of the devs of the MorphXT project and I use this lib in some
|
||||||
|
other of my projects, too. When I tried to upgrade the lib earlier for one
|
||||||
|
of my projects I had to realise that something did not work at first and
|
||||||
|
while most of the things were reasonably ease to be fixed. Now, the last
|
||||||
|
thing I encountered was not so easy to fix and I am uncertain if my fix is
|
||||||
|
any good so I'll just post it here and wait for some comments.
|
||||||
|
|
||||||
|
The problem was that I got an Access Violation when calling "UpnpInit". It
|
||||||
|
would call "ithread_rwlock_init(&GlobalHndRWLock, NULL)" which eventually
|
||||||
|
led to calling "pthread_cond_init" and I got the error notice at
|
||||||
|
"EnterCriticalSection (&ptw32_cond_list_lock);". It appeared that
|
||||||
|
"ptw32_cond_list_lock" was NULL. Now, I found two ways to fix this. Firstly
|
||||||
|
moving the whole block after at least one of the "ThreadPoolInit" calls
|
||||||
|
will fix the issue. Secondly, you could add:
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifdef PTW32_STATIC_LIB
|
||||||
|
// to get the following working we need this... is it a good patch or
|
||||||
|
not... I do not know!
|
||||||
|
pthread_win32_process_attach_np();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
right before "ithread_rwlock_init(&GlobalHndRWLock, NULL)".
|
||||||
|
|
||||||
|
Just so you know, I am using libupnp 1.6.6 and libpthreads 2.8.0 and both
|
||||||
|
are linked static into the binaries. I am currently using Visual Studio
|
||||||
|
2008 for development with Windows being the target OS. Any comment at your
|
||||||
|
end?
|
||||||
|
|
||||||
|
Regards, Stulle
|
||||||
|
|
||||||
|
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||||
* Forward port of svn revision 505:
|
* Forward port of svn revision 505:
|
||||||
SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
|
SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
|
||||||
Submitted By: zephyrus ( zephyrus00jp )
|
Submitted By: zephyrus ( zephyrus00jp )
|
||||||
|
@ -154,14 +154,19 @@ dnl # current: 3 -> 4
|
|||||||
dnl # revision: 6 -> 0
|
dnl # revision: 6 -> 0
|
||||||
dnl # - Interface has been removed in upnp
|
dnl # - Interface has been removed in upnp
|
||||||
dnl # age = 0
|
dnl # age = 0
|
||||||
|
dnl # - Code has changed in threadutil
|
||||||
|
dnl # revision: 3 -> 4
|
||||||
|
dnl # - Interfaces have been changed, added and removed in upnp
|
||||||
|
dnl # current: 4 -> 5
|
||||||
|
dnl # revision: 4 -> 0
|
||||||
dnl #
|
dnl #
|
||||||
dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0])
|
dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0])
|
||||||
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [4:3:2])
|
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2])
|
||||||
dnl #AC_SUBST([LT_VERSION_UPNP], [4:0:0])
|
dnl #AC_SUBST([LT_VERSION_UPNP], [4:0:0])
|
||||||
dnl #
|
dnl #
|
||||||
dnl ############################################################################
|
dnl ############################################################################
|
||||||
AC_SUBST([LT_VERSION_IXML], [2:4:0])
|
AC_SUBST([LT_VERSION_IXML], [2:4:0])
|
||||||
AC_SUBST([LT_VERSION_THREADUTIL], [4:3:2])
|
AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2])
|
||||||
AC_SUBST([LT_VERSION_UPNP], [4:0:0])
|
AC_SUBST([LT_VERSION_UPNP], [4:0:0])
|
||||||
dnl ############################################################################
|
dnl ############################################################################
|
||||||
dnl # Repeating the algorithm to place it closer to the modificatin place:
|
dnl # Repeating the algorithm to place it closer to the modificatin place:
|
||||||
|
@ -30,19 +30,21 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ITHREADH
|
#ifndef ITHREAD_H
|
||||||
#define ITHREADH
|
#define ITHREAD_H
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \file
|
* \file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "UpnpGlobal.h" /* For EXPORT_SPEC */
|
|
||||||
|
#include "UpnpGlobal.h" /* For UPNP_INLINE, EXPORT_SPEC */
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -94,6 +96,7 @@ extern "C" {
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
typedef pthread_t ithread_t;
|
typedef pthread_t ithread_t;
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ithread_attr_t
|
* Name: ithread_attr_t
|
||||||
*
|
*
|
||||||
@ -181,6 +184,95 @@ typedef pthread_rwlockattr_t ithread_rwlockattr_t;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
typedef pthread_rwlock_t ithread_rwlock_t;
|
typedef pthread_rwlock_t ithread_rwlock_t;
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: ithread_initialize_library
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initializes the library. Does nothing in all implementations, except
|
||||||
|
* when statically linked for WIN32.
|
||||||
|
* Parameters:
|
||||||
|
* none.
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, Nonzero on failure.
|
||||||
|
***************************************************************************/
|
||||||
|
static UPNP_INLINE int ithread_initialize_library(void) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(PTW32_STATIC_LIB)
|
||||||
|
ret = !pthread_win32_process_attach_np();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: ithread_cleanup_library
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Clean up library resources. Does nothing in all implementations, except
|
||||||
|
* when statically linked for WIN32.
|
||||||
|
* Parameters:
|
||||||
|
* none.
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, Nonzero on failure.
|
||||||
|
***************************************************************************/
|
||||||
|
static UPNP_INLINE int ithread_cleanup_library(void) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(PTW32_STATIC_LIB)
|
||||||
|
ret = !pthread_win32_process_detach_np();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: ithread_initialize_thread
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initializes the thread. Does nothing in all implementations, except
|
||||||
|
* when statically linked for WIN32.
|
||||||
|
* Parameters:
|
||||||
|
* none.
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, Nonzero on failure.
|
||||||
|
***************************************************************************/
|
||||||
|
static UPNP_INLINE int ithread_initialize_thread(void) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(PTW32_STATIC_LIB)
|
||||||
|
ret = !pthread_win32_thread_attach_np();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: ithread_cleanup_thread
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Clean up thread resources. Does nothing in all implementations, except
|
||||||
|
* when statically linked for WIN32.
|
||||||
|
* Parameters:
|
||||||
|
* none.
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, Nonzero on failure.
|
||||||
|
***************************************************************************/
|
||||||
|
static UPNP_INLINE int ithread_cleanup_thread(void) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(PTW32_STATIC_LIB)
|
||||||
|
ret = !pthread_win32_thread_detach_np();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_mutexattr_init
|
* Function: ithread_mutexattr_init
|
||||||
*
|
*
|
||||||
@ -517,7 +609,6 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
#define ithread_cond_init pthread_cond_init
|
#define ithread_cond_init pthread_cond_init
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_cond_signal
|
* Function: ithread_cond_signal
|
||||||
*
|
*
|
||||||
@ -577,22 +668,18 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Function: pthread_cond_timedwait
|
* Function: pthread_cond_timedwait
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Atomically releases the associated mutex and waits on the condition.
|
* Atomically releases the associated mutex and waits on the
|
||||||
* If the condition is not signaled in the specified time
|
* condition.
|
||||||
* than the
|
* If the condition is not signaled in the specified time than the
|
||||||
* call times out and returns.
|
* call times out and returns.
|
||||||
* Associated mutex MUST be locked by thread before entering
|
* Associated mutex MUST be locked by thread before entering this call.
|
||||||
* this call.
|
|
||||||
* Mutex is reacquired when call returns.
|
* Mutex is reacquired when call returns.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_cond_t * cond (must be valid non NULL pointer to
|
* ithread_cond_t *cond (must be valid non NULL pointer to ithread_cond_t)
|
||||||
* ithread_cond_t)
|
|
||||||
* cond must be initialized
|
* cond must be initialized
|
||||||
* ithread_mutex_t *mutex (must be valid non NULL pointer to
|
* ithread_mutex_t *mutex (must be valid non NULL pointer to ithread_mutex_t)
|
||||||
* ithread_mutex_t)
|
|
||||||
* Mutex must be locked.
|
* Mutex must be locked.
|
||||||
* const struct timespec *abstime (absolute time, measured
|
* const struct timespec *abstime (absolute time, measured from Jan 1, 1970)
|
||||||
* from Jan 1, 1970)
|
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 on success. ETIMEDOUT on timeout. Nonzero on failure.
|
* 0 on success. ETIMEDOUT on timeout. Nonzero on failure.
|
||||||
* See man page for pthread_cond_timedwait
|
* See man page for pthread_cond_timedwait
|
||||||
@ -664,6 +751,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#define ithread_exit pthread_exit
|
#define ithread_exit pthread_exit
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_get_current_thread_id
|
* Function: ithread_get_current_thread_id
|
||||||
*
|
*
|
||||||
@ -687,6 +775,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#define ithread_self pthread_self
|
#define ithread_self pthread_self
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_detach
|
* Function: ithread_detach
|
||||||
*
|
*
|
||||||
@ -700,6 +789,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#define ithread_detach pthread_detach
|
#define ithread_detach pthread_detach
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_join
|
* Function: ithread_join
|
||||||
*
|
*
|
||||||
@ -719,7 +809,6 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
#define ithread_join pthread_join
|
#define ithread_join pthread_join
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: isleep
|
* Function: isleep
|
||||||
*
|
*
|
||||||
@ -739,6 +828,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
#define isleep sleep
|
#define isleep sleep
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: isleep
|
* Function: isleep
|
||||||
*
|
*
|
||||||
@ -764,9 +854,11 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
EXPORT_SPEC int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind);
|
EXPORT_SPEC int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ITHREADH */
|
|
||||||
|
#endif /* ITHREAD_H */
|
||||||
|
|
||||||
|
@ -68,9 +68,6 @@ static unsigned long DiffMillis(struct timeval *time1, struct timeval *time2)
|
|||||||
{
|
{
|
||||||
double temp = 0;
|
double temp = 0;
|
||||||
|
|
||||||
assert(time1 != NULL);
|
|
||||||
assert(time2 != NULL);
|
|
||||||
|
|
||||||
temp = time1->tv_sec - time2->tv_sec;
|
temp = time1->tv_sec - time2->tv_sec;
|
||||||
/* convert to milliseconds */
|
/* convert to milliseconds */
|
||||||
temp *= 1000;
|
temp *= 1000;
|
||||||
@ -94,8 +91,6 @@ static unsigned long DiffMillis(struct timeval *time1, struct timeval *time2)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void StatsInit(ThreadPoolStats *stats)
|
static void StatsInit(ThreadPoolStats *stats)
|
||||||
{
|
{
|
||||||
assert(stats != NULL);
|
|
||||||
|
|
||||||
stats->totalIdleTime = 0;
|
stats->totalIdleTime = 0;
|
||||||
stats->totalJobsHQ = 0;
|
stats->totalJobsHQ = 0;
|
||||||
stats->totalJobsLQ = 0;
|
stats->totalJobsLQ = 0;
|
||||||
@ -205,9 +200,6 @@ static int CmpThreadPoolJob(void *jobA, void *jobB)
|
|||||||
ThreadPoolJob *a = (ThreadPoolJob *)jobA;
|
ThreadPoolJob *a = (ThreadPoolJob *)jobA;
|
||||||
ThreadPoolJob *b = (ThreadPoolJob *)jobB;
|
ThreadPoolJob *b = (ThreadPoolJob *)jobB;
|
||||||
|
|
||||||
assert(jobA != NULL);
|
|
||||||
assert(jobB != NULL);
|
|
||||||
|
|
||||||
return a->jobId == b->jobId;
|
return a->jobId == b->jobId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,8 +213,6 @@ static int CmpThreadPoolJob(void *jobA, void *jobB)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void FreeThreadPoolJob(ThreadPool *tp, ThreadPoolJob *tpj)
|
static void FreeThreadPoolJob(ThreadPool *tp, ThreadPoolJob *tpj)
|
||||||
{
|
{
|
||||||
assert(tp != NULL);
|
|
||||||
|
|
||||||
FreeListFree(&tp->jobFreeList, tpj);
|
FreeListFree(&tp->jobFreeList, tpj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,8 +330,6 @@ static void BumpPriority(ThreadPool *tp)
|
|||||||
unsigned long diffTime = 0;
|
unsigned long diffTime = 0;
|
||||||
ThreadPoolJob *tempJob = NULL;
|
ThreadPoolJob *tempJob = NULL;
|
||||||
|
|
||||||
assert(tp != NULL);
|
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
while (!done) {
|
while (!done) {
|
||||||
if (tp->medJobQ.size) {
|
if (tp->medJobQ.size) {
|
||||||
@ -389,12 +377,9 @@ static void SetRelTimeout( struct timespec *time, int relMillis )
|
|||||||
int sec = relMillis / 1000;
|
int sec = relMillis / 1000;
|
||||||
int milliSeconds = relMillis % 1000;
|
int milliSeconds = relMillis % 1000;
|
||||||
|
|
||||||
assert( time != NULL );
|
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
|
|
||||||
time->tv_sec = now.tv_sec + sec;
|
time->tv_sec = now.tv_sec + sec;
|
||||||
time->tv_nsec = ( (now.tv_usec/1000) + milliSeconds ) * 1000000;
|
time->tv_nsec = (now.tv_usec / 1000 + milliSeconds) * 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -420,7 +405,10 @@ static void SetSeed()
|
|||||||
srand((unsigned int)t.tv_usec + ithread_get_current_thread_id());
|
srand((unsigned int)t.tv_usec + ithread_get_current_thread_id());
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
volatile union { volatile pthread_t tid; volatile unsigned i; } idu;
|
volatile union {
|
||||||
|
volatile pthread_t tid;
|
||||||
|
volatile unsigned i;
|
||||||
|
} idu;
|
||||||
|
|
||||||
idu.tid = ithread_get_current_thread_id();
|
idu.tid = ithread_get_current_thread_id();
|
||||||
srand((unsigned int)t.millitm + idu.i);
|
srand((unsigned int)t.millitm + idu.i);
|
||||||
@ -453,15 +441,10 @@ static void *WorkerThread( void *arg )
|
|||||||
int retCode = 0;
|
int retCode = 0;
|
||||||
int persistent = -1;
|
int persistent = -1;
|
||||||
ThreadPool *tp = (ThreadPool *) arg;
|
ThreadPool *tp = (ThreadPool *) arg;
|
||||||
// allow static linking
|
|
||||||
#ifdef WIN32
|
|
||||||
#ifdef PTW32_STATIC_LIB
|
|
||||||
pthread_win32_thread_attach_np();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
assert( tp != NULL );
|
|
||||||
|
|
||||||
// Increment total thread count
|
ithread_initialize_thread();
|
||||||
|
|
||||||
|
/* Increment total thread count */
|
||||||
ithread_mutex_lock(&tp->mutex);
|
ithread_mutex_lock(&tp->mutex);
|
||||||
tp->totalThreads++;
|
tp->totalThreads++;
|
||||||
ithread_cond_broadcast(&tp->start_and_shutdown);
|
ithread_cond_broadcast(&tp->start_and_shutdown);
|
||||||
@ -482,71 +465,47 @@ static void *WorkerThread( void *arg )
|
|||||||
tp->stats.totalWorkTime += ( StatsTime( NULL ) - start ); // work time
|
tp->stats.totalWorkTime += ( StatsTime( NULL ) - start ); // work time
|
||||||
StatsTime( &start ); // idle time
|
StatsTime( &start ); // idle time
|
||||||
|
|
||||||
if( persistent == 1 ) {
|
if (persistent == 0) {
|
||||||
// Persistent thread
|
tp->stats.workerThreads--;
|
||||||
// becomes a regular thread
|
} else if (persistent == 1) {
|
||||||
|
/* Persistent thread becomes a regular thread */
|
||||||
tp->persistentThreads--;
|
tp->persistentThreads--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( persistent == 0 ) {
|
/* Check for a job or shutdown */
|
||||||
tp->stats.workerThreads--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for a job or shutdown
|
|
||||||
while (tp->lowJobQ.size == 0 &&
|
while (tp->lowJobQ.size == 0 &&
|
||||||
tp->medJobQ.size == 0 &&
|
tp->medJobQ.size == 0 &&
|
||||||
tp->highJobQ.size == 0 &&
|
tp->highJobQ.size == 0 &&
|
||||||
!tp->persistentJob &&
|
!tp->persistentJob && !tp->shutdown) {
|
||||||
!tp->shutdown ) {
|
/* If wait timed out and we currently have more than the
|
||||||
// If wait timed out
|
* min threads, or if we have more than the max threads
|
||||||
// and we currently have more than the
|
* (only possible if the attributes have been reset)
|
||||||
// min threads, or if we have more than the max threads
|
* let this thread die. */
|
||||||
// (only possible if the attributes have been reset)
|
|
||||||
// let this thread die.
|
|
||||||
if ((retCode == ETIMEDOUT &&
|
if ((retCode == ETIMEDOUT &&
|
||||||
tp->totalThreads > tp->attr.minThreads) ||
|
tp->totalThreads > tp->attr.minThreads) ||
|
||||||
(tp->attr.maxThreads != -1 &&
|
(tp->attr.maxThreads != -1 &&
|
||||||
tp->totalThreads > tp->attr.maxThreads)) {
|
tp->totalThreads > tp->attr.maxThreads)) {
|
||||||
tp->stats.idleThreads--;
|
tp->stats.idleThreads--;
|
||||||
tp->totalThreads--;
|
goto exit_function;
|
||||||
ithread_cond_broadcast( &tp->start_and_shutdown );
|
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
|
||||||
#ifdef WIN32
|
|
||||||
#ifdef PTW32_STATIC_LIB
|
|
||||||
// allow static linking
|
|
||||||
pthread_win32_thread_detach_np ();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
SetRelTimeout(&timeout, tp->attr.maxIdleTime);
|
SetRelTimeout(&timeout, tp->attr.maxIdleTime);
|
||||||
|
|
||||||
// wait for a job up to the specified max time
|
/* wait for a job up to the specified max time */
|
||||||
retCode = ithread_cond_timedwait(
|
retCode = ithread_cond_timedwait(
|
||||||
&tp->condition, &tp->mutex, &timeout);
|
&tp->condition, &tp->mutex, &timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
tp->stats.idleThreads--;
|
tp->stats.idleThreads--;
|
||||||
tp->stats.totalIdleTime += ( StatsTime( NULL ) - start ); // idle time
|
/* idle time */
|
||||||
StatsTime( &start ); // work time
|
tp->stats.totalIdleTime += StatsTime(NULL) - start;
|
||||||
|
/* work time */
|
||||||
// bump priority of starved jobs
|
StatsTime(&start);
|
||||||
|
/* bump priority of starved jobs */
|
||||||
BumpPriority(tp);
|
BumpPriority(tp);
|
||||||
|
/* if shutdown then stop */
|
||||||
// if shutdown then stop
|
|
||||||
if (tp->shutdown) {
|
if (tp->shutdown) {
|
||||||
tp->totalThreads--;
|
goto exit_function;
|
||||||
ithread_cond_broadcast( &tp->start_and_shutdown );
|
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
|
||||||
#ifdef WIN32
|
|
||||||
#ifdef PTW32_STATIC_LIB
|
|
||||||
// allow static linking
|
|
||||||
pthread_win32_thread_detach_np ();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
} else {
|
} else {
|
||||||
// Pick up persistent job if available
|
/* Pick up persistent job if available */
|
||||||
if (tp->persistentJob) {
|
if (tp->persistentJob) {
|
||||||
job = tp->persistentJob;
|
job = tp->persistentJob;
|
||||||
tp->persistentJob = NULL;
|
tp->persistentJob = NULL;
|
||||||
@ -556,7 +515,7 @@ static void *WorkerThread( void *arg )
|
|||||||
} else {
|
} else {
|
||||||
tp->stats.workerThreads++;
|
tp->stats.workerThreads++;
|
||||||
persistent = 0;
|
persistent = 0;
|
||||||
// Pick the highest priority job
|
/* Pick the highest priority job */
|
||||||
if (tp->highJobQ.size > 0) {
|
if (tp->highJobQ.size > 0) {
|
||||||
head = ListHead(&tp->highJobQ);
|
head = ListHead(&tp->highJobQ);
|
||||||
job = (ThreadPoolJob *) head->item;
|
job = (ThreadPoolJob *) head->item;
|
||||||
@ -573,14 +532,9 @@ static void *WorkerThread( void *arg )
|
|||||||
CalcWaitTime(tp, LOW_PRIORITY, job);
|
CalcWaitTime(tp, LOW_PRIORITY, job);
|
||||||
ListDelNode(&tp->lowJobQ, head, 0);
|
ListDelNode(&tp->lowJobQ, head, 0);
|
||||||
} else {
|
} else {
|
||||||
// Should never get here
|
/* Should never get here */
|
||||||
assert( 0 );
|
|
||||||
tp->stats.workerThreads--;
|
tp->stats.workerThreads--;
|
||||||
tp->totalThreads--;
|
goto exit_function;
|
||||||
ithread_cond_broadcast( &tp->start_and_shutdown );
|
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -588,20 +542,23 @@ static void *WorkerThread( void *arg )
|
|||||||
tp->busyThreads++;
|
tp->busyThreads++;
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
|
||||||
|
/* In the future can log info */
|
||||||
if (SetPriority(job->priority) != 0) {
|
if (SetPriority(job->priority) != 0) {
|
||||||
// In the future can log
|
|
||||||
// info
|
|
||||||
} else {
|
} else {
|
||||||
// In the future can log
|
|
||||||
// info
|
|
||||||
}
|
}
|
||||||
|
/* run the job */
|
||||||
// run the job
|
|
||||||
job->func(job->arg);
|
job->func(job->arg);
|
||||||
|
/* return to Normal */
|
||||||
// return to Normal
|
|
||||||
SetPriority(DEFAULT_PRIORITY);
|
SetPriority(DEFAULT_PRIORITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit_function:
|
||||||
|
tp->totalThreads--;
|
||||||
|
ithread_cond_broadcast(&tp->start_and_shutdown);
|
||||||
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
ithread_cleanup_thread();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -621,9 +578,6 @@ static ThreadPoolJob *CreateThreadPoolJob( ThreadPoolJob *job, int id, ThreadPoo
|
|||||||
{
|
{
|
||||||
ThreadPoolJob *newJob = NULL;
|
ThreadPoolJob *newJob = NULL;
|
||||||
|
|
||||||
assert( job != NULL );
|
|
||||||
assert( tp != NULL );
|
|
||||||
|
|
||||||
newJob = (ThreadPoolJob *)FreeListAlloc(&tp->jobFreeList);
|
newJob = (ThreadPoolJob *)FreeListAlloc(&tp->jobFreeList);
|
||||||
if (newJob) {
|
if (newJob) {
|
||||||
*newJob = *job;
|
*newJob = *job;
|
||||||
@ -656,13 +610,10 @@ static int CreateWorker( ThreadPool *tp )
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
int currentThreads = tp->totalThreads + 1;
|
int currentThreads = tp->totalThreads + 1;
|
||||||
|
|
||||||
assert( tp != NULL );
|
|
||||||
|
|
||||||
if (tp->attr.maxThreads != INFINITE_THREADS &&
|
if (tp->attr.maxThreads != INFINITE_THREADS &&
|
||||||
currentThreads > tp->attr.maxThreads) {
|
currentThreads > tp->attr.maxThreads) {
|
||||||
return EMAXTHREADS;
|
return EMAXTHREADS;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ithread_create(&temp, NULL, WorkerThread, tp);
|
rc = ithread_create(&temp, NULL, WorkerThread, tp);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
rc = ithread_detach(temp);
|
rc = ithread_detach(temp);
|
||||||
@ -670,7 +621,6 @@ static int CreateWorker( ThreadPool *tp )
|
|||||||
ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex);
|
ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tp->stats.maxThreads < tp->totalThreads) {
|
if (tp->stats.maxThreads < tp->totalThreads) {
|
||||||
tp->stats.maxThreads = tp->totalThreads;
|
tp->stats.maxThreads = tp->totalThreads;
|
||||||
}
|
}
|
||||||
@ -695,8 +645,6 @@ static void AddWorker(ThreadPool *tp)
|
|||||||
int jobs = 0;
|
int jobs = 0;
|
||||||
int threads = 0;
|
int threads = 0;
|
||||||
|
|
||||||
assert( tp != NULL );
|
|
||||||
|
|
||||||
jobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
|
jobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
|
||||||
threads = tp->totalThreads - tp->persistentThreads;
|
threads = tp->totalThreads - tp->persistentThreads;
|
||||||
while (threads == 0 ||
|
while (threads == 0 ||
|
||||||
@ -746,62 +694,38 @@ int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr )
|
|||||||
int retCode = 0;
|
int retCode = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
assert( tp != NULL );
|
if (!tp) {
|
||||||
if( tp == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
#ifdef WIN32
|
|
||||||
#ifdef PTW32_STATIC_LIB
|
|
||||||
pthread_win32_process_attach_np();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
retCode += ithread_mutex_init(&tp->mutex, NULL);
|
retCode += ithread_mutex_init(&tp->mutex, NULL);
|
||||||
assert( retCode == 0 );
|
|
||||||
|
|
||||||
retCode += ithread_mutex_lock(&tp->mutex);
|
retCode += ithread_mutex_lock(&tp->mutex);
|
||||||
assert( retCode == 0 );
|
|
||||||
|
|
||||||
retCode += ithread_cond_init(&tp->condition, NULL);
|
retCode += ithread_cond_init(&tp->condition, NULL);
|
||||||
assert( retCode == 0 );
|
|
||||||
|
|
||||||
retCode += ithread_cond_init(&tp->start_and_shutdown, NULL);
|
retCode += ithread_cond_init(&tp->start_and_shutdown, NULL);
|
||||||
assert( retCode == 0 );
|
if (retCode) {
|
||||||
|
|
||||||
if( retCode != 0 ) {
|
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr) {
|
if (attr) {
|
||||||
tp->attr = ( *attr );
|
tp->attr = *attr;
|
||||||
} else {
|
} else {
|
||||||
TPAttrInit(&tp->attr);
|
TPAttrInit(&tp->attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SetPolicyType(tp->attr.schedPolicy) != 0) {
|
if (SetPolicyType(tp->attr.schedPolicy) != 0) {
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
ithread_mutex_destroy(&tp->mutex);
|
ithread_mutex_destroy(&tp->mutex);
|
||||||
ithread_cond_destroy(&tp->condition);
|
ithread_cond_destroy(&tp->condition);
|
||||||
ithread_cond_destroy(&tp->start_and_shutdown);
|
ithread_cond_destroy(&tp->start_and_shutdown);
|
||||||
|
|
||||||
return INVALID_POLICY;
|
return INVALID_POLICY;
|
||||||
}
|
}
|
||||||
|
|
||||||
retCode += FreeListInit(
|
retCode += FreeListInit(
|
||||||
&tp->jobFreeList, sizeof(ThreadPoolJob), JOBFREELISTSIZE);
|
&tp->jobFreeList, sizeof(ThreadPoolJob), JOBFREELISTSIZE);
|
||||||
assert( retCode == 0 );
|
|
||||||
|
|
||||||
StatsInit(&tp->stats);
|
StatsInit(&tp->stats);
|
||||||
|
|
||||||
retCode += ListInit(&tp->highJobQ, CmpThreadPoolJob, NULL);
|
retCode += ListInit(&tp->highJobQ, CmpThreadPoolJob, NULL);
|
||||||
assert( retCode == 0 );
|
|
||||||
|
|
||||||
retCode += ListInit(&tp->medJobQ, CmpThreadPoolJob, NULL);
|
retCode += ListInit(&tp->medJobQ, CmpThreadPoolJob, NULL);
|
||||||
assert( retCode == 0 );
|
|
||||||
|
|
||||||
retCode += ListInit(&tp->lowJobQ, CmpThreadPoolJob, NULL);
|
retCode += ListInit(&tp->lowJobQ, CmpThreadPoolJob, NULL);
|
||||||
assert( retCode == 0 );
|
if (retCode) {
|
||||||
|
|
||||||
if( retCode != 0 ) {
|
|
||||||
retCode = EAGAIN;
|
retCode = EAGAIN;
|
||||||
} else {
|
} else {
|
||||||
tp->persistentJob = NULL;
|
tp->persistentJob = NULL;
|
||||||
@ -811,7 +735,8 @@ int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr )
|
|||||||
tp->busyThreads = 0;
|
tp->busyThreads = 0;
|
||||||
tp->persistentThreads = 0;
|
tp->persistentThreads = 0;
|
||||||
for (i = 0; i < tp->attr.minThreads; ++i) {
|
for (i = 0; i < tp->attr.minThreads; ++i) {
|
||||||
if( ( retCode = CreateWorker( tp ) ) != 0 ) {
|
retCode = CreateWorker(tp);
|
||||||
|
if (retCode) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -819,8 +744,8 @@ int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr )
|
|||||||
|
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
|
||||||
if( retCode != 0 ) {
|
if (retCode) {
|
||||||
// clean up if the min threads could not be created
|
/* clean up if the min threads could not be created */
|
||||||
ThreadPoolShutdown(tp);
|
ThreadPoolShutdown(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -848,59 +773,51 @@ int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int ThreadPoolAddPersistent(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
|
int ThreadPoolAddPersistent(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
int tempId = -1;
|
int tempId = -1;
|
||||||
ThreadPoolJob *temp = NULL;
|
ThreadPoolJob *temp = NULL;
|
||||||
|
|
||||||
assert( tp != NULL );
|
if (!tp || !job) {
|
||||||
assert( job != NULL );
|
|
||||||
if( ( tp == NULL ) || ( job == NULL ) ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
if (!jobId) {
|
||||||
if( jobId == NULL ) {
|
|
||||||
jobId = &tempId;
|
jobId = &tempId;
|
||||||
}
|
}
|
||||||
|
|
||||||
*jobId = INVALID_JOB_ID;
|
*jobId = INVALID_JOB_ID;
|
||||||
|
|
||||||
ithread_mutex_lock(&tp->mutex);
|
ithread_mutex_lock(&tp->mutex);
|
||||||
|
|
||||||
assert( job->priority == LOW_PRIORITY ||
|
/* Create A worker if less than max threads running */
|
||||||
job->priority == MED_PRIORITY ||
|
|
||||||
job->priority == HIGH_PRIORITY );
|
|
||||||
|
|
||||||
// Create A worker if less than max threads running
|
|
||||||
if (tp->totalThreads < tp->attr.maxThreads) {
|
if (tp->totalThreads < tp->attr.maxThreads) {
|
||||||
CreateWorker(tp);
|
CreateWorker(tp);
|
||||||
} else {
|
} else {
|
||||||
// if there is more than one worker thread
|
/* if there is more than one worker thread
|
||||||
// available then schedule job, otherwise fail
|
* available then schedule job, otherwise fail */
|
||||||
if (tp->totalThreads - tp->persistentThreads - 1 == 0) {
|
if (tp->totalThreads - tp->persistentThreads - 1 == 0) {
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
ret = EMAXTHREADS;
|
||||||
return EMAXTHREADS;
|
goto exit_function;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = CreateThreadPoolJob(job, tp->lastJobId, tp);
|
temp = CreateThreadPoolJob(job, tp->lastJobId, tp);
|
||||||
if( temp == NULL ) {
|
if (!temp) {
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
ret = EOUTOFMEM;
|
||||||
return EOUTOFMEM;
|
goto exit_function;
|
||||||
}
|
}
|
||||||
|
|
||||||
tp->persistentJob = temp;
|
tp->persistentJob = temp;
|
||||||
|
|
||||||
// Notify a waiting thread
|
/* Notify a waiting thread */
|
||||||
ithread_cond_signal(&tp->condition);
|
ithread_cond_signal(&tp->condition);
|
||||||
|
|
||||||
// wait until long job has been picked up
|
/* wait until long job has been picked up */
|
||||||
while( tp->persistentJob != NULL ) {
|
while (tp->persistentJob) {
|
||||||
ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex);
|
ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
*jobId = tp->lastJobId++;
|
*jobId = tp->lastJobId++;
|
||||||
|
|
||||||
|
exit_function:
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -924,42 +841,29 @@ int ThreadPoolAddPersistent( ThreadPool *tp, ThreadPoolJob *job, int *jobId )
|
|||||||
int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
|
int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
|
||||||
{
|
{
|
||||||
int rc = EOUTOFMEM;
|
int rc = EOUTOFMEM;
|
||||||
|
|
||||||
int tempId = -1;
|
int tempId = -1;
|
||||||
int totalJobs;
|
int totalJobs;
|
||||||
|
|
||||||
ThreadPoolJob *temp = NULL;
|
ThreadPoolJob *temp = NULL;
|
||||||
|
|
||||||
assert( tp != NULL );
|
if (!tp || !job) {
|
||||||
assert( job != NULL );
|
|
||||||
if( ( tp == NULL ) || ( job == NULL ) ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ithread_mutex_lock(&tp->mutex);
|
ithread_mutex_lock(&tp->mutex);
|
||||||
|
|
||||||
assert( job->priority == LOW_PRIORITY ||
|
|
||||||
job->priority == MED_PRIORITY ||
|
|
||||||
job->priority == HIGH_PRIORITY );
|
|
||||||
|
|
||||||
totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
|
totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
|
||||||
if (totalJobs >= tp->attr.maxJobsTotal) {
|
if (totalJobs >= tp->attr.maxJobsTotal) {
|
||||||
fprintf(stderr, "total jobs = %d, too many jobs", totalJobs);
|
fprintf(stderr, "total jobs = %d, too many jobs", totalJobs);
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
goto exit_function;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
if (!jobId) {
|
||||||
if( jobId == NULL ) {
|
|
||||||
jobId = &tempId;
|
jobId = &tempId;
|
||||||
}
|
}
|
||||||
*jobId = INVALID_JOB_ID;
|
*jobId = INVALID_JOB_ID;
|
||||||
|
|
||||||
temp = CreateThreadPoolJob(job, tp->lastJobId, tp);
|
temp = CreateThreadPoolJob(job, tp->lastJobId, tp);
|
||||||
if( temp == NULL ) {
|
if (!temp) {
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
goto exit_function;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (job->priority == HIGH_PRIORITY) {
|
if (job->priority == HIGH_PRIORITY) {
|
||||||
if (ListAddTail(&tp->highJobQ, temp)) {
|
if (ListAddTail(&tp->highJobQ, temp)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@ -974,10 +878,10 @@ int ThreadPoolAdd( ThreadPool *tp, ThreadPoolJob *job, int *jobId )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddWorker if appropriate
|
/* AddWorker if appropriate */
|
||||||
AddWorker(tp);
|
AddWorker(tp);
|
||||||
|
|
||||||
// Notify a waiting thread
|
/* Notify a waiting thread */
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
ithread_cond_signal(&tp->condition);
|
ithread_cond_signal(&tp->condition);
|
||||||
} else {
|
} else {
|
||||||
@ -986,6 +890,7 @@ int ThreadPoolAdd( ThreadPool *tp, ThreadPoolJob *job, int *jobId )
|
|||||||
|
|
||||||
*jobId = tp->lastJobId++;
|
*jobId = tp->lastJobId++;
|
||||||
|
|
||||||
|
exit_function:
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -1009,20 +914,17 @@ int ThreadPoolAdd( ThreadPool *tp, ThreadPoolJob *job, int *jobId )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out)
|
int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out)
|
||||||
{
|
{
|
||||||
ThreadPoolJob *temp = NULL;
|
|
||||||
int ret = INVALID_JOB_ID;
|
int ret = INVALID_JOB_ID;
|
||||||
|
ThreadPoolJob *temp = NULL;
|
||||||
ListNode *tempNode = NULL;
|
ListNode *tempNode = NULL;
|
||||||
ThreadPoolJob dummy;
|
ThreadPoolJob dummy;
|
||||||
|
|
||||||
assert( tp != NULL );
|
if (!tp) {
|
||||||
if( tp == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
if (!out) {
|
||||||
if( out == NULL ) {
|
|
||||||
out = &dummy;
|
out = &dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
dummy.jobId = jobId;
|
dummy.jobId = jobId;
|
||||||
|
|
||||||
ithread_mutex_lock(&tp->mutex);
|
ithread_mutex_lock(&tp->mutex);
|
||||||
@ -1033,9 +935,8 @@ int ThreadPoolRemove( ThreadPool *tp, int jobId, ThreadPoolJob *out )
|
|||||||
*out = *temp;
|
*out = *temp;
|
||||||
ListDelNode(&tp->highJobQ, tempNode, 0);
|
ListDelNode(&tp->highJobQ, tempNode, 0);
|
||||||
FreeThreadPoolJob(tp, temp);
|
FreeThreadPoolJob(tp, temp);
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
ret = 0;
|
||||||
|
goto exit_function;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tempNode = ListFind(&tp->medJobQ, NULL, &dummy);
|
tempNode = ListFind(&tp->medJobQ, NULL, &dummy);
|
||||||
@ -1044,31 +945,27 @@ int ThreadPoolRemove( ThreadPool *tp, int jobId, ThreadPoolJob *out )
|
|||||||
*out = *temp;
|
*out = *temp;
|
||||||
ListDelNode(&tp->medJobQ, tempNode, 0);
|
ListDelNode(&tp->medJobQ, tempNode, 0);
|
||||||
FreeThreadPoolJob(tp, temp);
|
FreeThreadPoolJob(tp, temp);
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
ret = 0;
|
||||||
|
goto exit_function;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tempNode = ListFind(&tp->lowJobQ, NULL, &dummy);
|
tempNode = ListFind(&tp->lowJobQ, NULL, &dummy);
|
||||||
if (tempNode) {
|
if (tempNode) {
|
||||||
temp = (ThreadPoolJob *)tempNode->item;
|
temp = (ThreadPoolJob *)tempNode->item;
|
||||||
*out = *temp;
|
*out = *temp;
|
||||||
ListDelNode(&tp->lowJobQ, tempNode, 0);
|
ListDelNode(&tp->lowJobQ, tempNode, 0);
|
||||||
FreeThreadPoolJob(tp, temp);
|
FreeThreadPoolJob(tp, temp);
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
ret = 0;
|
||||||
|
goto exit_function;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tp->persistentJob && tp->persistentJob->jobId == jobId) {
|
if (tp->persistentJob && tp->persistentJob->jobId == jobId) {
|
||||||
*out = *tp->persistentJob;
|
*out = *tp->persistentJob;
|
||||||
FreeThreadPoolJob(tp, tp->persistentJob);
|
FreeThreadPoolJob(tp, tp->persistentJob);
|
||||||
tp->persistentJob = NULL;
|
tp->persistentJob = NULL;
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
ret = 0;
|
||||||
|
goto exit_function;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit_function:
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1089,18 +986,13 @@ int ThreadPoolRemove( ThreadPool *tp, int jobId, ThreadPoolJob *out )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out)
|
int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out)
|
||||||
{
|
{
|
||||||
assert( tp != NULL );
|
if (!tp || !out) {
|
||||||
assert( out != NULL );
|
|
||||||
if( tp == NULL || out == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tp->shutdown) {
|
if (!tp->shutdown) {
|
||||||
ithread_mutex_lock(&tp->mutex);
|
ithread_mutex_lock(&tp->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = tp->attr;
|
*out = tp->attr;
|
||||||
|
|
||||||
if (!tp->shutdown) {
|
if (!tp->shutdown) {
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
}
|
}
|
||||||
@ -1127,42 +1019,39 @@ int ThreadPoolSetAttr( ThreadPool *tp, ThreadPoolAttr *attr )
|
|||||||
ThreadPoolAttr temp;
|
ThreadPoolAttr temp;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
assert( tp != NULL );
|
if (!tp) {
|
||||||
if( tp == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ithread_mutex_lock(&tp->mutex);
|
ithread_mutex_lock(&tp->mutex);
|
||||||
|
|
||||||
if( attr != NULL ) {
|
if (attr) {
|
||||||
temp = ( *attr );
|
temp = *attr;
|
||||||
} else {
|
} else {
|
||||||
TPAttrInit(&temp);
|
TPAttrInit(&temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SetPolicyType(temp.schedPolicy) != 0) {
|
if (SetPolicyType(temp.schedPolicy) != 0) {
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
|
||||||
return INVALID_POLICY;
|
return INVALID_POLICY;
|
||||||
}
|
}
|
||||||
|
tp->attr = temp;
|
||||||
tp->attr = ( temp );
|
/* add threads */
|
||||||
|
if (tp->totalThreads < tp->attr.minThreads) {
|
||||||
// add threads
|
|
||||||
if( tp->totalThreads < tp->attr.minThreads )
|
|
||||||
{
|
|
||||||
for (i = tp->totalThreads; i < tp->attr.minThreads; i++) {
|
for (i = tp->totalThreads; i < tp->attr.minThreads; i++) {
|
||||||
if( ( retCode = CreateWorker( tp ) ) != 0 ) {
|
retCode = CreateWorker(tp);
|
||||||
|
if (retCode != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* signal changes */
|
||||||
// signal changes
|
|
||||||
ithread_cond_signal(&tp->condition);
|
ithread_cond_signal(&tp->condition);
|
||||||
|
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
|
||||||
if (retCode != 0) {
|
if (retCode != 0) {
|
||||||
// clean up if the min threads could not be created
|
/* clean up if the min threads could not be created */
|
||||||
ThreadPoolShutdown(tp);
|
ThreadPoolShutdown(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1188,14 +1077,13 @@ int ThreadPoolShutdown( ThreadPool *tp )
|
|||||||
ListNode *head = NULL;
|
ListNode *head = NULL;
|
||||||
ThreadPoolJob *temp = NULL;
|
ThreadPoolJob *temp = NULL;
|
||||||
|
|
||||||
assert( tp != NULL );
|
if (!tp) {
|
||||||
if( tp == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ithread_mutex_lock(&tp->mutex);
|
ithread_mutex_lock(&tp->mutex);
|
||||||
|
|
||||||
// clean up high priority jobs
|
/* clean up high priority jobs */
|
||||||
while (tp->highJobQ.size) {
|
while (tp->highJobQ.size) {
|
||||||
head = ListHead(&tp->highJobQ);
|
head = ListHead(&tp->highJobQ);
|
||||||
temp = (ThreadPoolJob *)head->item;
|
temp = (ThreadPoolJob *)head->item;
|
||||||
@ -1207,7 +1095,7 @@ int ThreadPoolShutdown( ThreadPool *tp )
|
|||||||
}
|
}
|
||||||
ListDestroy(&tp->highJobQ, 0);
|
ListDestroy(&tp->highJobQ, 0);
|
||||||
|
|
||||||
// clean up med priority jobs
|
/* clean up med priority jobs */
|
||||||
while (tp->medJobQ.size) {
|
while (tp->medJobQ.size) {
|
||||||
head = ListHead(&tp->medJobQ);
|
head = ListHead(&tp->medJobQ);
|
||||||
temp = (ThreadPoolJob *)head->item;
|
temp = (ThreadPoolJob *)head->item;
|
||||||
@ -1219,7 +1107,7 @@ int ThreadPoolShutdown( ThreadPool *tp )
|
|||||||
}
|
}
|
||||||
ListDestroy(&tp->medJobQ, 0);
|
ListDestroy(&tp->medJobQ, 0);
|
||||||
|
|
||||||
// clean up low priority jobs
|
/* clean up low priority jobs */
|
||||||
while (tp->lowJobQ.size) {
|
while (tp->lowJobQ.size) {
|
||||||
head = ListHead(&tp->lowJobQ);
|
head = ListHead(&tp->lowJobQ);
|
||||||
temp = (ThreadPoolJob *)head->item;
|
temp = (ThreadPoolJob *)head->item;
|
||||||
@ -1231,7 +1119,7 @@ int ThreadPoolShutdown( ThreadPool *tp )
|
|||||||
}
|
}
|
||||||
ListDestroy(&tp->lowJobQ, 0);
|
ListDestroy(&tp->lowJobQ, 0);
|
||||||
|
|
||||||
// clean up long term job
|
/* clean up long term job */
|
||||||
if (tp->persistentJob) {
|
if (tp->persistentJob) {
|
||||||
temp = tp->persistentJob;
|
temp = tp->persistentJob;
|
||||||
if (temp->free_func) {
|
if (temp->free_func) {
|
||||||
@ -1240,28 +1128,27 @@ int ThreadPoolShutdown( ThreadPool *tp )
|
|||||||
FreeThreadPoolJob(tp, temp);
|
FreeThreadPoolJob(tp, temp);
|
||||||
tp->persistentJob = NULL;
|
tp->persistentJob = NULL;
|
||||||
}
|
}
|
||||||
|
/* signal shutdown */
|
||||||
// signal shutdown
|
|
||||||
tp->shutdown = 1;
|
tp->shutdown = 1;
|
||||||
ithread_cond_broadcast(&tp->condition);
|
ithread_cond_broadcast(&tp->condition);
|
||||||
|
/* wait for all threads to finish */
|
||||||
// wait for all threads to finish
|
|
||||||
while (tp->totalThreads > 0) {
|
while (tp->totalThreads > 0) {
|
||||||
ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex);
|
ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex);
|
||||||
}
|
}
|
||||||
|
/* destroy condition */
|
||||||
// destroy condition
|
|
||||||
while (ithread_cond_destroy(&tp->condition) != 0) {
|
while (ithread_cond_destroy(&tp->condition) != 0) {
|
||||||
|
/**/
|
||||||
}
|
}
|
||||||
while (ithread_cond_destroy(&tp->start_and_shutdown) != 0) {
|
while (ithread_cond_destroy(&tp->start_and_shutdown) != 0) {
|
||||||
|
/**/
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeListDestroy(&tp->jobFreeList);
|
FreeListDestroy(&tp->jobFreeList);
|
||||||
|
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
|
|
||||||
// destroy mutex
|
/* destroy mutex */
|
||||||
while (ithread_mutex_destroy(&tp->mutex) != 0) {
|
while (ithread_mutex_destroy(&tp->mutex) != 0) {
|
||||||
|
/**/
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1280,11 +1167,9 @@ int ThreadPoolShutdown( ThreadPool *tp )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPAttrInit(ThreadPoolAttr *attr)
|
int TPAttrInit(ThreadPoolAttr *attr)
|
||||||
{
|
{
|
||||||
assert( attr != NULL );
|
if (!attr) {
|
||||||
if( attr == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->jobsPerThread = DEFAULT_JOBS_PER_THREAD;
|
attr->jobsPerThread = DEFAULT_JOBS_PER_THREAD;
|
||||||
attr->maxIdleTime = DEFAULT_IDLE_TIME;
|
attr->maxIdleTime = DEFAULT_IDLE_TIME;
|
||||||
attr->maxThreads = DEFAULT_MAX_THREADS;
|
attr->maxThreads = DEFAULT_MAX_THREADS;
|
||||||
@ -1312,12 +1197,9 @@ int TPAttrInit( ThreadPoolAttr *attr )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg)
|
int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg)
|
||||||
{
|
{
|
||||||
assert( job != NULL );
|
if (!job || !func) {
|
||||||
assert( func != NULL );
|
|
||||||
if( job == NULL || func == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
job->func = func;
|
job->func = func;
|
||||||
job->arg = arg;
|
job->arg = arg;
|
||||||
job->priority = DEFAULT_PRIORITY;
|
job->priority = DEFAULT_PRIORITY;
|
||||||
@ -1340,11 +1222,9 @@ int TPJobInit( ThreadPoolJob *job, start_routine func, void *arg )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority)
|
int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority)
|
||||||
{
|
{
|
||||||
assert( job != NULL );
|
if (!job) {
|
||||||
if( job == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority == LOW_PRIORITY ||
|
if (priority == LOW_PRIORITY ||
|
||||||
priority == MED_PRIORITY ||
|
priority == MED_PRIORITY ||
|
||||||
priority == HIGH_PRIORITY) {
|
priority == HIGH_PRIORITY) {
|
||||||
@ -1368,11 +1248,9 @@ int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func)
|
int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func)
|
||||||
{
|
{
|
||||||
assert( job != NULL );
|
if(!job) {
|
||||||
if( job == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
job->free_func = func;
|
job->free_func = func;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1391,11 +1269,9 @@ int TPJobSetFreeFunction( ThreadPoolJob *job, free_routine func )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads)
|
int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads)
|
||||||
{
|
{
|
||||||
assert( attr != NULL );
|
if (!attr) {
|
||||||
if( attr == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->maxThreads = maxThreads;
|
attr->maxThreads = maxThreads;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1414,11 +1290,9 @@ int TPAttrSetMaxThreads( ThreadPoolAttr *attr, int maxThreads )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads)
|
int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads)
|
||||||
{
|
{
|
||||||
assert( attr != NULL );
|
if (!attr) {
|
||||||
if( attr == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->minThreads = minThreads;
|
attr->minThreads = minThreads;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1436,11 +1310,9 @@ int TPAttrSetMinThreads( ThreadPoolAttr *attr, int minThreads )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime)
|
int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime)
|
||||||
{
|
{
|
||||||
assert( attr != NULL );
|
if (!attr) {
|
||||||
if( attr == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->maxIdleTime = idleTime;
|
attr->maxIdleTime = idleTime;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1458,11 +1330,9 @@ int TPAttrSetIdleTime( ThreadPoolAttr *attr, int idleTime )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread)
|
int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread)
|
||||||
{
|
{
|
||||||
assert( attr != NULL );
|
if (!attr) {
|
||||||
if( attr == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->jobsPerThread = jobsPerThread;
|
attr->jobsPerThread = jobsPerThread;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1480,11 +1350,9 @@ int TPAttrSetJobsPerThread( ThreadPoolAttr *attr, int jobsPerThread )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime)
|
int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime)
|
||||||
{
|
{
|
||||||
assert( attr != NULL );
|
if (!attr) {
|
||||||
if( attr == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->starvationTime = starvationTime;
|
attr->starvationTime = starvationTime;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1503,11 +1371,9 @@ int TPAttrSetStarvationTime( ThreadPoolAttr *attr, int starvationTime )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy)
|
int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy)
|
||||||
{
|
{
|
||||||
assert( attr != NULL );
|
if (!attr) {
|
||||||
if( attr == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->schedPolicy = schedPolicy;
|
attr->schedPolicy = schedPolicy;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1526,11 +1392,9 @@ int TPAttrSetSchedPolicy( ThreadPoolAttr *attr, PolicyType schedPolicy )
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal)
|
int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal)
|
||||||
{
|
{
|
||||||
assert( attr != NULL );
|
if (!attr) {
|
||||||
if( attr == NULL ) {
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->maxJobsTotal = maxJobsTotal;
|
attr->maxJobsTotal = maxJobsTotal;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1540,11 +1404,9 @@ int TPAttrSetMaxJobsTotal( ThreadPoolAttr *attr, int maxJobsTotal )
|
|||||||
#ifdef STATS
|
#ifdef STATS
|
||||||
void ThreadPoolPrintStats(ThreadPoolStats *stats)
|
void ThreadPoolPrintStats(ThreadPoolStats *stats)
|
||||||
{
|
{
|
||||||
assert( stats != NULL );
|
if (!stats) {
|
||||||
if (stats == NULL) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* some OSses time_t length may depending on platform, promote it to long for safety */
|
/* some OSses time_t length may depending on platform, promote it to long for safety */
|
||||||
printf("ThreadPoolStats at Time: %ld\n", (long)StatsTime(NULL));
|
printf("ThreadPoolStats at Time: %ld\n", (long)StatsTime(NULL));
|
||||||
printf("High Jobs pending: %d\n", stats->currentJobsHQ);
|
printf("High Jobs pending: %d\n", stats->currentJobsHQ);
|
||||||
@ -1580,13 +1442,11 @@ void ThreadPoolPrintStats(ThreadPoolStats *stats)
|
|||||||
#ifdef STATS
|
#ifdef STATS
|
||||||
int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats)
|
int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats)
|
||||||
{
|
{
|
||||||
assert(tp != NULL);
|
|
||||||
assert(stats != NULL);
|
|
||||||
if (tp == NULL || stats == NULL) {
|
if (tp == NULL || stats == NULL) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if not shutdown then acquire mutex
|
/* if not shutdown then acquire mutex */
|
||||||
if (!tp->shutdown) {
|
if (!tp->shutdown) {
|
||||||
ithread_mutex_lock(&tp->mutex);
|
ithread_mutex_lock(&tp->mutex);
|
||||||
}
|
}
|
||||||
@ -1597,26 +1457,22 @@ int ThreadPoolGetStats( ThreadPool *tp, ThreadPoolStats *stats )
|
|||||||
} else {
|
} else {
|
||||||
stats->avgWaitHQ = 0;
|
stats->avgWaitHQ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats->totalJobsMQ > 0) {
|
if (stats->totalJobsMQ > 0) {
|
||||||
stats->avgWaitMQ = stats->totalTimeMQ / stats->totalJobsMQ;
|
stats->avgWaitMQ = stats->totalTimeMQ / stats->totalJobsMQ;
|
||||||
} else {
|
} else {
|
||||||
stats->avgWaitMQ = 0;
|
stats->avgWaitMQ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats->totalJobsLQ > 0) {
|
if (stats->totalJobsLQ > 0) {
|
||||||
stats->avgWaitLQ = stats->totalTimeLQ / stats->totalJobsLQ;
|
stats->avgWaitLQ = stats->totalTimeLQ / stats->totalJobsLQ;
|
||||||
} else {
|
} else {
|
||||||
stats->avgWaitLQ = 0;
|
stats->avgWaitLQ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
stats->totalThreads = tp->totalThreads;
|
stats->totalThreads = tp->totalThreads;
|
||||||
stats->persistentThreads = tp->persistentThreads;
|
stats->persistentThreads = tp->persistentThreads;
|
||||||
stats->currentJobsHQ = ListSize( &tp->highJobQ );
|
stats->currentJobsHQ = ListSize( &tp->highJobQ );
|
||||||
stats->currentJobsLQ = ListSize( &tp->lowJobQ );
|
stats->currentJobsLQ = ListSize( &tp->lowJobQ );
|
||||||
stats->currentJobsMQ = ListSize( &tp->medJobQ );
|
stats->currentJobsMQ = ListSize( &tp->medJobQ );
|
||||||
|
/* if not shutdown then release mutex */
|
||||||
//if not shutdown then release mutex
|
|
||||||
if (!tp->shutdown) {
|
if (!tp->shutdown) {
|
||||||
ithread_mutex_unlock(&tp->mutex);
|
ithread_mutex_unlock(&tp->mutex);
|
||||||
}
|
}
|
||||||
@ -1628,6 +1484,7 @@ int ThreadPoolGetStats( ThreadPool *tp, ThreadPoolStats *stats )
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
||||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
||||||
#else
|
#else
|
||||||
@ -1640,8 +1497,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz)
|
|||||||
unsigned __int64 tmpres = 0;
|
unsigned __int64 tmpres = 0;
|
||||||
static int tzflag;
|
static int tzflag;
|
||||||
|
|
||||||
if (NULL != tv)
|
if (tv) {
|
||||||
{
|
|
||||||
GetSystemTimeAsFileTime(&ft);
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
|
||||||
tmpres |= ft.dwHighDateTime;
|
tmpres |= ft.dwHighDateTime;
|
||||||
@ -1654,11 +1510,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz)
|
|||||||
tv->tv_sec = (long)(tmpres / 1000000UL);
|
tv->tv_sec = (long)(tmpres / 1000000UL);
|
||||||
tv->tv_usec = (long)(tmpres % 1000000UL);
|
tv->tv_usec = (long)(tmpres % 1000000UL);
|
||||||
}
|
}
|
||||||
|
if (tz) {
|
||||||
if (NULL != tz)
|
if (!tzflag) {
|
||||||
{
|
|
||||||
if (!tzflag)
|
|
||||||
{
|
|
||||||
_tzset();
|
_tzset();
|
||||||
tzflag++;
|
tzflag++;
|
||||||
}
|
}
|
||||||
@ -1669,3 +1522,4 @@ int gettimeofday(struct timeval *tv, struct timezone *tz)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
@ -204,6 +204,9 @@ int UpnpInit(const char *HostIP, unsigned short DestPort)
|
|||||||
{
|
{
|
||||||
int retVal = UPNP_E_SUCCESS;
|
int retVal = UPNP_E_SUCCESS;
|
||||||
|
|
||||||
|
/* Initializes the ithread library */
|
||||||
|
ithread_initialize_library();
|
||||||
|
|
||||||
ithread_mutex_lock(&gSDKInitMutex);
|
ithread_mutex_lock(&gSDKInitMutex);
|
||||||
|
|
||||||
/* Check if we're already initialized. */
|
/* Check if we're already initialized. */
|
||||||
@ -257,6 +260,9 @@ int UpnpInit2(const char *IfName, unsigned short DestPort)
|
|||||||
{
|
{
|
||||||
int retVal;
|
int retVal;
|
||||||
|
|
||||||
|
/* Initializes the ithread library */
|
||||||
|
ithread_initialize_library();
|
||||||
|
|
||||||
ithread_mutex_lock(&gSDKInitMutex);
|
ithread_mutex_lock(&gSDKInitMutex);
|
||||||
|
|
||||||
/* Check if we're already initialized. */
|
/* Check if we're already initialized. */
|
||||||
@ -308,10 +314,6 @@ int UpnpFinish(void)
|
|||||||
#endif
|
#endif
|
||||||
struct Handle_Info *temp;
|
struct Handle_Info *temp;
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
/*WSACleanup();*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( UpnpSdkInit != 1 ) {
|
if( UpnpSdkInit != 1 ) {
|
||||||
return UPNP_E_FINISH;
|
return UPNP_E_FINISH;
|
||||||
}
|
}
|
||||||
@ -361,15 +363,11 @@ int UpnpFinish(void)
|
|||||||
ithread_rwlock_destroy(&GlobalHndRWLock);
|
ithread_rwlock_destroy(&GlobalHndRWLock);
|
||||||
ithread_mutex_destroy(&gUUIDMutex);
|
ithread_mutex_destroy(&gUUIDMutex);
|
||||||
|
|
||||||
// remove all virtual dirs
|
/* remove all virtual dirs */
|
||||||
UpnpRemoveAllVirtualDirs();
|
UpnpRemoveAllVirtualDirs();
|
||||||
|
|
||||||
// allow static linking
|
/* Clean-up ithread library resources */
|
||||||
#ifdef WIN32
|
ithread_cleanup_library();
|
||||||
#ifdef PTW32_STATIC_LIB
|
|
||||||
pthread_win32_thread_detach_np();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
UpnpSdkInit = 0;
|
UpnpSdkInit = 0;
|
||||||
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user