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/error_handling.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