Exemple #1
0
/* What each thread is doing
* 
* In principle this is an endless loop. The only time this loop gets interuppted is once
* thpool_destroy() is invoked or the program exits.
* 
* @param  thread        thread that will run this function
* @return nothing
*/
static void* thread_do(struct thread* thread_p){
	/* Set thread name for profiling and debuging */
	char thread_name[128] = {0};
	sprintf(thread_name, "thread-pool-%d", thread_p->id);
	prctl(PR_SET_NAME, thread_name);

	/* Assure all threads have been created before starting serving */
	thpool_* thpool_p = thread_p->thpool_p;
	
	/* Register signal handler */
	struct sigaction act;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_handler = thread_hold;
	if (sigaction(SIGUSR1, &act, NULL) == -1) {
		fprintf(stderr, "thread_do(): cannot handle SIGUSR1");
	}
	
	/* Mark thread as alive (initialized) */
	pthread_mutex_lock(&thpool_p->thcount_lock);
	thpool_p->num_threads_alive += 1;
	pthread_mutex_unlock(&thpool_p->thcount_lock);

	while(threads_keepalive){

		bsem_wait(thpool_p->jobqueue.has_jobs);

		if (threads_keepalive){
			
			pthread_mutex_lock(&thpool_p->thcount_lock);
			thpool_p->num_threads_working++;
			pthread_mutex_unlock(&thpool_p->thcount_lock);
			
			/* Read job from queue and execute it */
			void*(*func_buff)(void* arg);
			void*  arg_buff;
			job* job_p = jobqueue_pull(&thpool_p->jobqueue);
			if (job_p) {
				func_buff = job_p->function;
				arg_buff  = job_p->arg;
				func_buff(arg_buff);
				free(job_p);
			}
			
			pthread_mutex_lock(&thpool_p->thcount_lock);
			thpool_p->num_threads_working--;
			if (!thpool_p->num_threads_working) {
				pthread_cond_signal(&thpool_p->threads_all_idle);
			}
			pthread_mutex_unlock(&thpool_p->thcount_lock);

		}
	}
	pthread_mutex_lock(&thpool_p->thcount_lock);
	thpool_p->num_threads_alive --;
	pthread_mutex_unlock(&thpool_p->thcount_lock);

	return NULL;
}
Exemple #2
0
/* Clear the queue */
static void jobqueue_clear(thpool_* thpool_p){
	while(thpool_p->jobqueue_p->len){
		free(jobqueue_pull(thpool_p));
	}

	thpool_p->jobqueue_p->front = NULL;
	thpool_p->jobqueue_p->rear  = NULL;
	bsem_reset(thpool_p->jobqueue_p->has_jobs);
	thpool_p->jobqueue_p->len = 0;

}
Exemple #3
0
/* What each thread is doing
* 
* In principle this is an endless loop. The only time this loop gets interuppted is once
* thpool_destroy() is invoked or the program exits.
* 
* @param  thread        thread that will run this function
* @return nothing
*/
static void* thread_do(struct thread* thread_p){

	/* Assure all threads have been created before starting serving */
	thpool_* thpool_p = thread_p->thpool_p;
	
	/* Register signal handler */
	struct sigaction act;
	act.sa_handler = thread_hold;
	if (sigaction(SIGUSR1, &act, NULL) == -1) {
		fprintf(stderr, "thread_do(): cannot handle SIGUSR1");
	}
	
	/* Mark thread as alive (initialized) */
	pthread_mutex_lock(&thpool_p->thcount_lock);
	thpool_p->num_threads_alive += 1;
	pthread_mutex_unlock(&thpool_p->thcount_lock);

	while(threads_keepalive){

		bsem_wait(thpool_p->jobqueue_p->has_jobs);

		if (threads_keepalive){
			
			pthread_mutex_lock(&thpool_p->thcount_lock);
			thpool_p->num_threads_working++;
			pthread_mutex_unlock(&thpool_p->thcount_lock);
			
			/* Read job from queue and execute it */
			void*(*func_buff)(void* arg);
			void*  arg_buff;
			job* job_p;
			pthread_mutex_lock(&thpool_p->jobqueue_p->rwmutex);
			job_p = jobqueue_pull(thpool_p);
			pthread_mutex_unlock(&thpool_p->jobqueue_p->rwmutex);
			if (job_p) {
				func_buff = job_p->function;
				arg_buff  = job_p->arg;
				func_buff(arg_buff);
				free(job_p);
			}
			
			pthread_mutex_lock(&thpool_p->thcount_lock);
			thpool_p->num_threads_working--;
			pthread_mutex_unlock(&thpool_p->thcount_lock);

		}
	}
	pthread_mutex_lock(&thpool_p->thcount_lock);
	thpool_p->num_threads_alive --;
	pthread_mutex_unlock(&thpool_p->thcount_lock);

	return NULL;
}
Exemple #4
0
/* Clear the queue */
static void jobqueue_clear(jobqueue* jobqueue_p){

	while(jobqueue_p->len){
		free(jobqueue_pull(jobqueue_p));
	}

	jobqueue_p->front = NULL;
	jobqueue_p->rear  = NULL;
	bsem_reset(jobqueue_p->has_jobs);
	jobqueue_p->len = 0;

}
Exemple #5
0
/* Clear the queue */
static void jobqueue_clear(ThPool* thpool) {
    WorkGroup* group;
    int size;

    do {
        group = jobqueue_pull(thpool, -1);
        if (group == NULL) {
            size = 0;
        } else {
            size = group->size;
            free(group->jobs);
            free(group);
        }
    } while (size > 0);

    thpool->jobqueue->front = NULL;
    thpool->jobqueue->rear = NULL;
    bsem_reset(thpool->jobqueue->has_jobs);
    thpool->jobqueue->len = 0;
    thpool->jobqueue->group_front = NULL;
    thpool->jobqueue->total_time = 0;
    thpool->jobqueue->highest_expected_return = 0;
}
Exemple #6
0
/* What each thread is doing
*
* In principle this is an endless loop. The only time this loop gets interuppted is once
* thpool_destroy() is invoked or the program exits.
*
* @param  thread        thread that will run this function
* @return nothing
*/
static void* thread_do(struct thread* thread_p)
{

    /* Set thread name for profiling and debuging */
    char thread_name[128] = {0};
    sprintf(thread_name, "thread-pool-%d", thread_p->id);

#if defined(__linux__)
    /* Use prctl instead to prevent using _GNU_SOURCE flag and implicit declaration */
    prctl(PR_SET_NAME, thread_name);
#elif defined(__APPLE__) && defined(__MACH__)
    pthread_setname_np(thread_name);
#else
    err("thread_do(): pthread_setname_np is not supported on this system");
#endif

    /* Assure all threads have been created before starting serving */
    thpool_* thpool_p = thread_p->thpool_p;

    /* Register signal handler */
    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    act.sa_handler = thread_hold;

    if (sigaction(SIGUSR1, &act, NULL) == -1) {
        err("thread_do(): cannot handle SIGUSR1");
    }

    /* Mark thread as alive (initialized) */
    pthread_mutex_lock(&thpool_p->thcount_lock);
    thpool_p->num_threads_alive += 1;
    pthread_mutex_unlock(&thpool_p->thcount_lock);

    while (threads_keepalive) {

        bsem_wait(thpool_p->jobqueue.has_jobs);

        if (threads_keepalive) {

            pthread_mutex_lock(&thpool_p->thcount_lock);
            thpool_p->num_threads_working++;
            pthread_mutex_unlock(&thpool_p->thcount_lock);

            /* Read job from queue and execute it */
            void (*func_buff)(void*);
            void*  arg_buff;
            job* job_p = jobqueue_pull(&thpool_p->jobqueue);

            if (job_p) {
                func_buff = job_p->function;
                arg_buff  = job_p->arg;
                func_buff(arg_buff);
                free(job_p);
            }

            pthread_mutex_lock(&thpool_p->thcount_lock);
            thpool_p->num_threads_working--;

            if (!thpool_p->num_threads_working) {
                pthread_cond_signal(&thpool_p->threads_all_idle);
            }

            pthread_mutex_unlock(&thpool_p->thcount_lock);

        }
    }

    pthread_mutex_lock(&thpool_p->thcount_lock);
    thpool_p->num_threads_alive --;
    pthread_mutex_unlock(&thpool_p->thcount_lock);

    return NULL;
}
Exemple #7
0
/* What each thread is doing
*
* In principle this is an endless loop. The only time this loop gets interrupted is once
* thpool_destroy() is invoked or the program exits.
*
* @param  thread        thread that will run this function
* @return nothing
*/
static void* thread_do(Thread* thread) {
    float elapsed;
    int info;
    struct timespec cputime;
    JobQueue* queue;
    WorkGroup* workGroup;
    Job* job;
    thpool_function_type func_buff;
    void* arg_buff;
    int i;

    /* Set thread name for profiling and debugging */
    char thread_name[128] = {0};
    sprintf(thread_name, "thread-pool-%d", thread->id);

#if defined(__linux__)
    /* Use prctl instead to prevent using _GNU_SOURCE flag and implicit declaration */
    prctl(PR_SET_NAME, thread_name);
#elif defined(__APPLE__) && defined(__MACH__)
    pthread_setname_np(thread_name);
#else
    fprintf(stderr, "thread_do(): pthread_setname_np is not supported on this system");
#endif

    /* Assure all threads have been created before starting serving */
    ThPool* thpool = thread->thpool;

    /* Mark thread as alive (initialized) */
    pthread_mutex_lock(&thpool->thcount_lock);
    thpool->num_threads_alive += 1;
    pthread_mutex_unlock(&thpool->thcount_lock);

    queue = thpool->jobqueue;

    while (thpool->threads_keepalive) {

        bsem_wait(queue->has_jobs);

        if (!thpool->threads_keepalive) {
            break;
        }

        pthread_mutex_lock(&thpool->thcount_lock);
        thpool->num_threads_working++;
        pthread_mutex_unlock(&thpool->thcount_lock);

        while (thpool->threads_keepalive) {
            /* Read job from queue and execute it */
            pthread_mutex_lock(&queue->rwmutex);
            workGroup = jobqueue_pull(thpool, thread->id);
            pthread_mutex_unlock(&queue->rwmutex);

            if (workGroup == NULL)
                break;

            if (cppadcg_pool_verbose) {
                get_monotonic_time2(&workGroup->startTime);
            }

            for (i = 0; i < workGroup->size; ++i) {
                job = &workGroup->jobs[i];

                if (cppadcg_pool_verbose) {
                    get_monotonic_time2(&job->startTime);
                }

                int do_benchmark = job->elapsed != NULL;
                if (do_benchmark) {
                    elapsed = -get_thread_time(&cputime, &info);
                }

                /* Execute the job */
                func_buff = job->function;
                arg_buff = job->arg;
                func_buff(arg_buff);

                if (do_benchmark && info == 0) {
                    elapsed += get_thread_time(&cputime, &info);
                    if (info == 0) {
                        (*job->elapsed) = elapsed;
                    }
                }

                if (cppadcg_pool_verbose) {
                    get_monotonic_time2(&job->endTime);
                }
            }

            if (cppadcg_pool_verbose) {
                get_monotonic_time2(&workGroup->endTime);

                if (thread->processed_groups == NULL) {
                    thread->processed_groups = workGroup;
                } else {
                    workGroup->prev = thread->processed_groups;
                    thread->processed_groups = workGroup;
                }
            } else {
                free(workGroup->jobs);
                free(workGroup);
            }
        }

        pthread_mutex_lock(&thpool->thcount_lock);
        thpool->num_threads_working--;
        if (!thpool->num_threads_working) {
            pthread_cond_signal(&thpool->threads_all_idle);
        }
        pthread_mutex_unlock(&thpool->thcount_lock);
    }

    pthread_mutex_lock(&thpool->thcount_lock);
    thpool->num_threads_alive--;
    pthread_mutex_unlock(&thpool->thcount_lock);

    return NULL;
}