예제 #1
0
/* There are two scenarios here. One is everything works as it should and second if
 * the thpool is to be killed. In that manner we try to BYPASS sem_wait and end each thread. */
void thpool_thread_do(thpool_t* tp_p){

	while(thpool_keepalive){
		
		if (sem_wait(tp_p->jobqueue->queueSem)) {/* WAITING until there is work in the queue */
			perror("thpool_thread_do(): Waiting for semaphore");
			exit(1);
		}

		if (thpool_keepalive){
			
			/* Read job from queue and execute it */
			void*(*func_buff)(void* arg);
			void*  arg_buff;
			thpool_job_t* job_p;
	
			pthread_mutex_lock(&mutex);                  /* LOCK */
			
			job_p = thpool_jobqueue_peek(tp_p);
			func_buff=job_p->function;
			arg_buff =job_p->arg;
			thpool_jobqueue_removelast(tp_p);
			
			pthread_mutex_unlock(&mutex);                /* UNLOCK */
			
			func_buff(arg_buff);               			 /* run function */
			free(job_p);                                                       /* DEALLOC job */
		}
		else
		{
			return; /* EXIT thread*/
		}
	}
	return;
}
예제 #2
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;
}
예제 #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;
}
예제 #4
0
// roda a fila
void poolWheel( piscina* dados )
{
	do{
//espera ateh que tenha trabalho na fila		
		sem_wait(dados->TarefaFila->filaSemaforo);
   
		if ( segura )
		{			
// passa tarefa para fila e executa
// Hic Sunt Dracones
			void *(*func_buff) (void* arg);
			void* arg_buff;

			piscina_tarefa* job_p;
	
			pthread_mutex_lock( &morfo );               			
			job_p = piscina_fila_peek(dados);
			if ( job_p == NULL )
			{
				piscina_fila_removelast( dados );
				pthread_mutex_unlock( &morfo );
				return;
			}
			
			func_buff = job_p->function;
			arg_buff = job_p->arg;
			piscina_fila_removelast( dados );
			pthread_mutex_unlock( &morfo );                
// roda a função			
			func_buff( arg_buff );      
         		if(job_p != NULL)
			{		
				free( job_p );  
				job_p=NULL; 
			}

			segura--;                                                    
		}
		else
		{
			return; 
		}
		
	}while ( segura );
	
	return;
}
예제 #5
0
void thpool_thread_do (thpool_t *tp_p){
    while (thpool_keepalive)
    {
        if (sem_wait (tp_p->jobqueue->queueSem))  //如果工作队列中没有工作,那么所有的线程都将在这里阻塞,当他调用成功的时候,信号量-1
        {
            fprintf(stderr , "Waiting for semaphore\n");
            exit (1);
        }

        if (thpool_keepalive)
        {
            void *(*func_buff) (void *arg);
            void *arg_buff;
            thpool_job_t *job_p;

            pthread_mutex_lock (&mutex);
            job_p = thpool_jobqueue_peek (tp_p);
                func_buff = job_p->function ;
            arg_buff= job_p->arg ;
            thpool_jobqueue_removelast (tp_p);
            pthread_mutex_unlock (&mutex);
            
            func_buff (arg_buff);
        
            free (job_p);
        }
        else 
        {
            return ;
        }
    }
    return ;



    
}
예제 #6
0
파일: thpool.c 프로젝트: jasonblog/note
/* 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;
}
예제 #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;
}