/**************************************************************************** * Function: ThreadPoolAddPersistent * * Description: * Adds a long term 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 * job-> valid ThreadPoolJob pointer with following fields * func - ThreadFunction to run * arg - argument to function. * priority - priority of job. * free_function - function to use when freeing argument * 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 ) { int tempId = -1; ThreadPoolJob *temp = NULL; assert( tp != NULL ); assert( job != NULL ); if( ( tp == NULL ) || ( job == NULL ) ) { return EINVAL; } if( jobId == NULL ) { jobId = &tempId; } *jobId = INVALID_JOB_ID; ithread_mutex_lock( &tp->mutex ); assert( job->priority == LOW_PRIORITY || job->priority == MED_PRIORITY || job->priority == HIGH_PRIORITY ); // Create A worker if less than max threads running if( tp->totalThreads < tp->attr.maxThreads ) { CreateWorker( tp ); } else { // if there is more than one worker thread // available then schedule job, otherwise fail if( tp->totalThreads - tp->persistentThreads - 1 == 0 ) { ithread_mutex_unlock( &tp->mutex ); return EMAXTHREADS; } } temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); if( temp == NULL ) { ithread_mutex_unlock( &tp->mutex ); return EOUTOFMEM; } tp->persistentJob = temp; // Notify a waiting thread ithread_cond_signal( &tp->condition ); // wait until long job has been picked up while( tp->persistentJob != NULL ) { ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex ); } *jobId = tp->lastJobId++; ithread_mutex_unlock( &tp->mutex ); return 0; }
int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId) { int rc = EOUTOFMEM; int tempId = -1; long totalJobs; ThreadPoolJob *temp = NULL; if (!tp || !job) return EINVAL; ithread_mutex_lock(&tp->mutex); totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size; if (totalJobs >= tp->attr.maxJobsTotal) { fprintf(stderr, "total jobs = %ld, too many jobs", totalJobs); goto exit_function; } if (!jobId) jobId = &tempId; *jobId = INVALID_JOB_ID; temp = CreateThreadPoolJob(job, tp->lastJobId, tp); if (!temp) goto exit_function; switch (job->priority) { case HIGH_PRIORITY: if (ListAddTail(&tp->highJobQ, temp)) rc = 0; break; case MED_PRIORITY: if (ListAddTail(&tp->medJobQ, temp)) rc = 0; break; default: if (ListAddTail(&tp->lowJobQ, temp)) rc = 0; } /* AddWorker if appropriate */ AddWorker(tp); /* Notify a waiting thread */ if (rc == 0) ithread_cond_signal(&tp->condition); else FreeThreadPoolJob(tp, temp); *jobId = tp->lastJobId++; exit_function: ithread_mutex_unlock(&tp->mutex); return rc; }
int ThreadPoolAddPersistent(ThreadPool *tp, ThreadPoolJob *job, int *jobId) { int ret = 0; int tempId = -1; ThreadPoolJob *temp = NULL; if (!tp || !job) { return EINVAL; } if (!jobId) { jobId = &tempId; } *jobId = INVALID_JOB_ID; ithread_mutex_lock(&tp->mutex); /* Create A worker if less than max threads running */ if (tp->totalThreads < tp->attr.maxThreads) { CreateWorker(tp); } else { /* if there is more than one worker thread * available then schedule job, otherwise fail */ if (tp->totalThreads - tp->persistentThreads - 1 == 0) { ret = EMAXTHREADS; goto exit_function; } } temp = CreateThreadPoolJob(job, tp->lastJobId, tp); if (!temp) { ret = EOUTOFMEM; goto exit_function; } tp->persistentJob = temp; /* Notify a waiting thread */ ithread_cond_signal(&tp->condition); /* wait until long job has been picked up */ while (tp->persistentJob) ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex); *jobId = tp->lastJobId++; exit_function: ithread_mutex_unlock(&tp->mutex); return ret; }
/**************************************************************************** * 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. * jobId - id of job * duration - whether or not this is a persistent thread * 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 ) { int rc = EOUTOFMEM; int tempId = -1; int totalJobs; ThreadPoolJob *temp = NULL; assert( tp != NULL ); assert( job != NULL ); if( ( tp == NULL ) || ( job == NULL ) ) { return EINVAL; } 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; if (totalJobs >= tp->attr.maxJobsTotal) { fprintf(stderr, "total jobs = %d, too many jobs", totalJobs); ithread_mutex_unlock( &tp->mutex ); return rc; } if( jobId == NULL ) { jobId = &tempId; } *jobId = INVALID_JOB_ID; temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); if( temp == NULL ) { ithread_mutex_unlock( &tp->mutex ); return rc; } if( job->priority == HIGH_PRIORITY ) { if( ListAddTail( &tp->highJobQ, temp ) ) { rc = 0; } } else if( job->priority == MED_PRIORITY ) { if( ListAddTail( &tp->medJobQ, temp ) ) { rc = 0; } } else { if( ListAddTail( &tp->lowJobQ, temp ) ) { rc = 0; } } // AddWorker if appropriate AddWorker( tp ); // Notify a waiting thread if( rc == 0 ) { ithread_cond_signal( &tp->condition ); } else { FreeThreadPoolJob( tp, temp ); } *jobId = tp->lastJobId++; ithread_mutex_unlock( &tp->mutex ); return rc; }