Esempio n. 1
0
/****************************************************************************
 * 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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
/****************************************************************************
 * 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;
}