00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #ifndef STXXL_SEMAPHORE_HEADER
00014 #define STXXL_SEMAPHORE_HEADER
00015 
00016 #ifdef STXXL_BOOST_THREADS
00017  #include <boost/thread/mutex.hpp>
00018  #include <boost/thread/condition.hpp>
00019 #else
00020  #include <pthread.h>
00021 #endif
00022 
00023 #include <stxxl/bits/noncopyable.h>
00024 #include <stxxl/bits/common/utils.h>
00025 
00026 
00027 __STXXL_BEGIN_NAMESPACE
00028 
00029 class semaphore : private noncopyable
00030 {
00031     int v;
00032 #ifdef STXXL_BOOST_THREADS
00033     boost::mutex mutex;
00034     boost::condition cond;
00035 #else
00036     pthread_mutex_t mutex;
00037     pthread_cond_t cond;
00038 #endif
00039 
00040 public:
00041     semaphore(int init_value = 1) : v(init_value)
00042     {
00043 #ifndef STXXL_BOOST_THREADS
00044         check_pthread_call(pthread_mutex_init(&mutex, NULL));
00045         check_pthread_call(pthread_cond_init(&cond, NULL));
00046 #endif
00047     }
00048     ~semaphore()
00049     {
00050 #ifndef STXXL_BOOST_THREADS
00051         int res = pthread_mutex_trylock(&mutex);
00052 
00053         if (res == 0 || res == EBUSY) {
00054             check_pthread_call(pthread_mutex_unlock(&mutex));
00055         } else
00056             stxxl_function_error(resource_error);
00057         check_pthread_call(pthread_mutex_destroy(&mutex));
00058         check_pthread_call(pthread_cond_destroy(&cond));
00059 #endif
00060     }
00061     
00062     
00063     int operator ++ (int)
00064     {
00065 #ifdef STXXL_BOOST_THREADS
00066         boost::mutex::scoped_lock Lock(mutex);
00067         int res = ++v;
00068         Lock.unlock();
00069         cond.notify_one();
00070 #else
00071         check_pthread_call(pthread_mutex_lock(&mutex));
00072         int res = ++v;
00073         check_pthread_call(pthread_mutex_unlock(&mutex));
00074         check_pthread_call(pthread_cond_signal(&cond));
00075 #endif
00076         return res;
00077     }
00078     
00079     
00080     int operator -- (int)
00081     {
00082 #ifdef STXXL_BOOST_THREADS
00083         boost::mutex::scoped_lock Lock(mutex);
00084         while (v <= 0)
00085             cond.wait(Lock);
00086 
00087         int res = --v;
00088 #else
00089         check_pthread_call(pthread_mutex_lock(&mutex));
00090         while (v <= 0)
00091             check_pthread_call(pthread_cond_wait(&cond, &mutex));
00092 
00093         int res = --v;
00094         check_pthread_call(pthread_mutex_unlock(&mutex));
00095 #endif
00096         return res;
00097     }
00098     
00099     
00100     
00101     
00102     
00103     int decrement()
00104     {
00105 #ifdef STXXL_BOOST_THREADS
00106         boost::mutex::scoped_lock Lock(mutex);
00107         return (--v);
00108 #else
00109         check_pthread_call(pthread_mutex_lock(&mutex));
00110         int res = --v;
00111         check_pthread_call(pthread_mutex_unlock(&mutex));
00112         return res;
00113 #endif
00114     }
00115     
00116     
00117     
00118     
00119     
00120     
00121     
00122     
00123     
00124     
00125 };
00126 
00127 __STXXL_END_NAMESPACE
00128 
00129 #endif // !STXXL_SEMAPHORE_HEADER