/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/utils/eh_thread_pool.c

Go to the documentation of this file.
00001 /* Thread pools */
00002 #include <eh_utils.h>
00003 #include <pthread.h>
00004 
00005 void
00006 tpool_init(tpool_t *tpoolp, int num_worker_threads, int max_queue_size, int do_not_block_when_full)
00007 {
00008    int i, rtn;
00009    tpool_t tpool;
00010    pthread_attr_t attr;
00011 
00012    pthread_attr_init( &attr );
00013    pthread_attr_setscope( &attr , PTHREAD_SCOPE_SYSTEM );
00014 
00015 //   if ( (tpool = (tpool_t)malloc(sizeof(struct tpool))) == NULL )
00016 //      perror("malloc"), eh_exit(-1);
00017 //   tpool = (tpool_t)eh_malloc( sizeof(tpool_t) , NULL , __FILE__ , __LINE__ );
00018    tpool = eh_new( struct tpool , 1 );
00019 
00020    tpool->num_threads = num_worker_threads;
00021    tpool->max_queue_size = max_queue_size;
00022    tpool->do_not_block_when_full = do_not_block_when_full;
00023 //   if ( (tpool->threads = (pthread_t*)malloc(sizeof(pthread_t)*num_worker_threads)) == NULL )
00024 //      perror("malloc"), eh_exit(-1);
00025    tpool->threads = eh_new( pthread_t , num_worker_threads );
00026    
00027    tpool->cur_queue_size = 0;
00028    tpool->queue_head = NULL;
00029    tpool->queue_tail = NULL;
00030    tpool->queue_closed = 0;
00031    tpool->shutdown = 0;
00032    if ( (rtn=pthread_mutex_init(&(tpool->queue_lock),NULL)) != 0 )
00033       fprintf(stderr,"pthread_mutex_init %s",strerror(rtn)), eh_exit(-1);
00034    if ( (rtn=pthread_cond_init(&(tpool->queue_not_empty),NULL)) != 0 )
00035       fprintf(stderr,"pthread_cond_init %s",strerror(rtn)), eh_exit(-1);
00036    if ( (rtn=pthread_cond_init(&(tpool->queue_not_full),NULL)) != 0 )
00037       fprintf(stderr,"pthread_cond_init %s",strerror(rtn)), eh_exit(-1);
00038    if ( (rtn=pthread_cond_init(&(tpool->queue_empty),NULL)) != 0 )
00039       fprintf(stderr,"pthread_cond_init %s",strerror(rtn)), eh_exit(-1);
00040 
00041    for ( i=0 ; i!=num_worker_threads ; i++ )
00042       if ( (rtn=pthread_create( &(tpool->threads[i]) , &attr , (void *(*)(void*))tpool_thread , (void*)tpool )) != 0 )
00043          fprintf(stderr,"pthread_create %d",rtn), eh_exit(-1);
00044 
00045    pthread_attr_destroy(&attr);
00046 
00047    *tpoolp = tpool;
00048 }
00049 
00050 void
00051 tpool_thread( tpool_t tpool )
00052 {
00053    tpool_work_t *my_workp;
00054 
00055    for (;;)
00056    {
00057       pthread_mutex_lock( &(tpool->queue_lock) );
00058       while ( (tpool->cur_queue_size==0) && (!tpool->shutdown) )
00059       {
00060          pthread_cond_wait( &(tpool->queue_not_empty) , &(tpool->queue_lock) );
00061       }
00062 
00063       if ( tpool->shutdown )
00064       {
00065          pthread_mutex_unlock( &(tpool->queue_lock) );
00066          pthread_exit( NULL );
00067       }
00068 
00069       my_workp = tpool->queue_head;
00070       tpool->cur_queue_size--;
00071       if ( tpool->cur_queue_size == 0 )
00072          tpool->queue_head = tpool->queue_tail = NULL;
00073       else
00074          tpool->queue_head = my_workp->next;
00075 
00076       if ( (!tpool->do_not_block_when_full) && (tpool->cur_queue_size==(tpool->max_queue_size-1)) )
00077          pthread_cond_broadcast( &(tpool->queue_not_full) );
00078 
00079       if ( tpool->cur_queue_size == 0 )
00080          pthread_cond_signal( &(tpool->queue_empty) );
00081 
00082       pthread_mutex_unlock( &(tpool->queue_lock) );
00083       (*(my_workp->routine))(my_workp->arg);
00084       eh_free(my_workp);
00085    }
00086 }
00087 
00088 int
00089 tpool_add_work( tpool_t tpool , void *routine , void *arg )
00090 {
00091    tpool_work_t *workp;
00092    pthread_mutex_lock( &(tpool->queue_lock) );
00093 
00094    if (    ( tpool->cur_queue_size==tpool->max_queue_size )
00095         && tpool->do_not_block_when_full )
00096    {
00097       pthread_mutex_unlock( &(tpool->queue_lock) );
00098       return -1;
00099    }
00100 
00101    while (    ( tpool->cur_queue_size==tpool->max_queue_size )
00102            && ( !(tpool->shutdown || tpool->queue_closed) ) )
00103    {
00104       pthread_cond_wait( &(tpool->queue_not_full) , &(tpool->queue_lock) );
00105    }
00106 
00107    if ( tpool->shutdown || tpool->queue_closed )
00108    {
00109       pthread_mutex_unlock( &(tpool->queue_lock) );
00110       return -1;
00111    }
00112 
00113 //   workp = (tpool_work_t*)malloc(sizeof(tpool_work_t));
00114    workp = eh_new( tpool_work_t , 1 );
00115    workp->routine = (void(*)())routine;
00116    workp->arg = arg;
00117    workp->next = NULL;
00118    if ( tpool->cur_queue_size == 0 )
00119    {
00120       tpool->queue_tail = tpool->queue_head = workp;
00121       pthread_cond_broadcast( &(tpool->queue_not_empty) );
00122    }
00123    else
00124    {
00125       (tpool->queue_tail)->next = workp;
00126       tpool->queue_tail = workp;
00127    }
00128    tpool->cur_queue_size++;
00129 
00130    pthread_mutex_unlock( &(tpool->queue_lock) );
00131    return 1;
00132 }
00133 
00134 int
00135 tpool_destroy( tpool_t tpool , int finish )
00136 {
00137    int i, rtn;
00138    tpool_work_t *cur_nodep;
00139 
00140    if ( (rtn=pthread_mutex_lock( &(tpool->queue_lock) )) != 0 )
00141       fprintf(stderr,"pthread_mutex_lock %d",rtn), eh_exit(-1);
00142 
00143    if ( tpool->queue_closed || tpool->shutdown )
00144    {
00145       if ( (rtn=pthread_mutex_unlock( &(tpool->queue_lock) )) != 0 )
00146          fprintf(stderr,"pthread_mutex_unlock %d",rtn), eh_exit(-1);
00147       return 0;
00148    }
00149 
00150    tpool->queue_closed = 1;
00151 
00152    if ( finish==1 )
00153    {
00154       while ( tpool->cur_queue_size!=0 )
00155          if ( (rtn=pthread_cond_wait( &(tpool->queue_empty) , &(tpool->queue_lock) )) != 0 )
00156             fprintf(stderr,"pthread_cond_wait %d",rtn), eh_exit(-1);
00157    }
00158 
00159    tpool->shutdown = 1;
00160 
00161    if ( (rtn=pthread_mutex_unlock( &(tpool->queue_lock) ))!=0 )
00162       fprintf(stderr,"pthread_mutex_unlock %d",rtn), eh_exit(-1);
00163 
00164    if ( (rtn=pthread_cond_broadcast( &(tpool->queue_not_empty) ))!=0 )
00165       fprintf(stderr,"pthread_cond_broadcast %d",rtn), eh_exit(-1);
00166    if ( (rtn=pthread_cond_broadcast( &(tpool->queue_not_full) ))!=0 )
00167      fprintf(stderr,"pthread_cond_broadcast %d",rtn), eh_exit(-1);
00168 
00169    for ( i=0 ; i<tpool->num_threads ; i++ )
00170    {
00171       if ( (rtn=pthread_join( tpool->threads[i] , NULL ))!=0 )
00172          fprintf(stderr,"pthread_join %d",rtn), eh_exit(-1);
00173    }
00174 
00175    eh_free(tpool->threads);
00176    while ( tpool->queue_head != NULL )
00177    {
00178       cur_nodep = tpool->queue_head->next;
00179       tpool->queue_head = tpool->queue_head->next;
00180       eh_free(cur_nodep);
00181    }
00182    eh_free(tpool);
00183    return 0 ;
00184 }
00185 

Generated on Fri Jan 4 18:04:16 2008 for sedflux by  doxygen 1.5.2