/**************************************************************************** * 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 ) { int retCode = 0; ThreadPoolAttr temp; int i = 0; assert( tp != NULL ); if( tp == NULL ) { return EINVAL; } ithread_mutex_lock( &tp->mutex ); if( attr != NULL ) { temp = ( *attr ); } else { TPAttrInit( &temp ); } if( SetPolicyType( temp.schedPolicy ) != 0 ) { ithread_mutex_unlock( &tp->mutex ); return INVALID_POLICY; } tp->attr = ( temp ); // add threads if( tp->totalThreads < tp->attr.minThreads ) { for( i = tp->totalThreads; i < tp->attr.minThreads; i++ ) { if( ( retCode = CreateWorker( tp ) ) != 0 ) { break; } } } // signal changes ithread_cond_signal( &tp->condition ); ithread_mutex_unlock( &tp->mutex ); if( retCode != 0 ) { // clean up if the min threads could not be created ThreadPoolShutdown( tp ); } return retCode; }
int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr) { int retCode = 0; ThreadPoolAttr temp; int i = 0; if (!tp) return EINVAL; ithread_mutex_lock(&tp->mutex); if (attr) temp = *attr; else TPAttrInit(&temp); if (SetPolicyType(temp.schedPolicy) != 0) { ithread_mutex_unlock(&tp->mutex); return INVALID_POLICY; } tp->attr = temp; /* add threads */ if (tp->totalThreads < tp->attr.minThreads) { for (i = tp->totalThreads; i < tp->attr.minThreads; i++) { retCode = CreateWorker(tp); if (retCode != 0) { break; } } } /* signal changes */ ithread_cond_signal(&tp->condition); ithread_mutex_unlock(&tp->mutex); if (retCode != 0) /* clean up if the min threads could not be created */ ThreadPoolShutdown(tp); return retCode; }
int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr) { int retCode = 0; int i = 0; if (!tp) { return EINVAL; } retCode += ithread_mutex_init(&tp->mutex, NULL); retCode += ithread_mutex_lock(&tp->mutex); retCode += ithread_cond_init(&tp->condition, NULL); retCode += ithread_cond_init(&tp->start_and_shutdown, NULL); if (retCode) { ithread_mutex_unlock(&tp->mutex); ithread_mutex_destroy(&tp->mutex); ithread_cond_destroy(&tp->condition); ithread_cond_destroy(&tp->start_and_shutdown); return EAGAIN; } if (attr) { tp->attr = *attr; } else { TPAttrInit(&tp->attr); } if (SetPolicyType(tp->attr.schedPolicy) != 0) { ithread_mutex_unlock(&tp->mutex); ithread_mutex_destroy(&tp->mutex); ithread_cond_destroy(&tp->condition); ithread_cond_destroy(&tp->start_and_shutdown); return INVALID_POLICY; } retCode += FreeListInit( &tp->jobFreeList, sizeof(ThreadPoolJob), JOBFREELISTSIZE); StatsInit(&tp->stats); retCode += ListInit(&tp->highJobQ, CmpThreadPoolJob, NULL); retCode += ListInit(&tp->medJobQ, CmpThreadPoolJob, NULL); retCode += ListInit(&tp->lowJobQ, CmpThreadPoolJob, NULL); if (retCode) { retCode = EAGAIN; } else { tp->persistentJob = NULL; tp->lastJobId = 0; tp->shutdown = 0; tp->totalThreads = 0; tp->busyThreads = 0; tp->persistentThreads = 0; tp->pendingWorkerThreadStart = 0; for (i = 0; i < tp->attr.minThreads; ++i) { retCode = CreateWorker(tp); if (retCode) { break; } } } ithread_mutex_unlock(&tp->mutex); if (retCode) { /* clean up if the min threads could not be created */ ThreadPoolShutdown(tp); } return retCode; }
/**************************************************************************** * 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. * 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 ) { int retCode = 0; int i = 0; //printf("%s, %d\n", __FUNCTION__, __LINE__); assert( tp != NULL ); if( tp == NULL ) { return EINVAL; } #ifdef WIN32 #ifdef PTW32_STATIC_LIB pthread_win32_process_attach_np(); #endif #endif //printf("%s, %d\n", __FUNCTION__, __LINE__); retCode += ithread_mutex_init( &tp->mutex, NULL ); assert( retCode == 0 ); retCode += ithread_mutex_lock( &tp->mutex ); assert( retCode == 0 ); retCode += ithread_cond_init( &tp->condition, NULL ); assert( retCode == 0 ); retCode += ithread_cond_init( &tp->start_and_shutdown, NULL ); assert( retCode == 0 ); //printf("%s, %d\n", __FUNCTION__, __LINE__); if( retCode != 0 ) { return EAGAIN; } if( attr ) { tp->attr = ( *attr ); } else { TPAttrInit( &tp->attr ); } //printf("%s, %d, minthreads: %d\n", __FUNCTION__, __LINE__, tp->attr.minThreads); if( SetPolicyType( tp->attr.schedPolicy ) != 0 ) { ithread_mutex_unlock( &tp->mutex ); ithread_mutex_destroy( &tp->mutex ); ithread_cond_destroy( &tp->condition ); ithread_cond_destroy( &tp->start_and_shutdown ); return INVALID_POLICY; } //printf("%s, %d\n", __FUNCTION__, __LINE__); retCode += FreeListInit( &tp->jobFreeList, sizeof( ThreadPoolJob ), JOBFREELISTSIZE ); assert( retCode == 0 ); StatsInit( &tp->stats ); retCode += ListInit( &tp->highJobQ, CmpThreadPoolJob, NULL ); assert( retCode == 0 ); retCode += ListInit( &tp->medJobQ, CmpThreadPoolJob, NULL ); assert( retCode == 0 ); retCode += ListInit( &tp->lowJobQ, CmpThreadPoolJob, NULL ); assert( retCode == 0 ); //printf("%s, %d, retcode is %d\n", __FUNCTION__, __LINE__, retCode); if( retCode != 0 ) { retCode = EAGAIN; //printf("%s, %d\n", __FUNCTION__, __LINE__); } else { //printf("%s, %d\n", __FUNCTION__, __LINE__); tp->persistentJob = NULL; tp->lastJobId = 0; tp->shutdown = 0; tp->totalThreads = 0; tp->persistentThreads = 0; //printf("%s, %d\n", __FUNCTION__, __LINE__); for( i = 0; i < tp->attr.minThreads; ++i ) { if( ( retCode = CreateWorker( tp ) ) != 0 ) { //printf("%s, %d\n", __FUNCTION__, __LINE__); break; } } } //printf("%s, %d\n", __FUNCTION__, __LINE__); ithread_mutex_unlock( &tp->mutex ); if( retCode != 0 ) { // clean up if the min threads could not be created ThreadPoolShutdown( tp ); } //printf("%s, %d\n", __FUNCTION__, __LINE__); return retCode; }