00001
00002
00003
00004
00005 #include "barrier.h"
00006
00007 #include "log.h"
00008
00009 #include <errno.h>
00010 #include <string.h>
00011 #include <pthread.h>
00012
00013 using namespace std;
00014
00015 namespace eq
00016 {
00017 namespace base
00018 {
00019 class BarrierPrivate
00020 {
00021 public:
00022 BarrierPrivate() : count( 0 ) {}
00023
00024 pthread_mutex_t mutex;
00025 pthread_cond_t cond;
00026 size_t count;
00027 };
00028
00029 Barrier::Barrier()
00030 : _data( new BarrierPrivate( ))
00031 {
00032
00033 int error = pthread_mutex_init( &_data->mutex, 0 );
00034 if( error )
00035 {
00036 EQERROR << "Error creating pthread mutex: " << strerror( error )
00037 << endl;
00038 return;
00039 }
00040
00041 error = pthread_cond_init( &_data->cond, 0 );
00042 if( error )
00043 {
00044 EQERROR << "Error creating pthread condition: "
00045 << strerror( error ) << endl;
00046 return;
00047 }
00048 }
00049
00050 Barrier::~Barrier()
00051 {
00052 pthread_mutex_destroy( &_data->mutex );
00053 pthread_cond_destroy( &_data->cond );
00054 delete _data;
00055 _data = 0;
00056 }
00057
00058 size_t Barrier::enter( const size_t size )
00059 {
00060 pthread_mutex_lock( &_data->mutex );
00061 const size_t pos = _data->count++;
00062
00063 if( _data->count >= size )
00064 {
00065 _data->count = 0;
00066 pthread_cond_broadcast( &_data->cond );
00067 pthread_mutex_unlock( &_data->mutex );
00068 }
00069 else
00070 {
00071 pthread_cond_wait( &_data->cond, &_data->mutex );
00072 pthread_mutex_unlock( &_data->mutex );
00073 }
00074 return pos;
00075 }
00076 }
00077 }