Stxxl  1.4.0
include/stxxl/bits/common/semaphore.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  include/stxxl/bits/common/semaphore.h
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de>
00007  *
00008  *  Distributed under the Boost Software License, Version 1.0.
00009  *  (See accompanying file LICENSE_1_0.txt or copy at
00010  *  http://www.boost.org/LICENSE_1_0.txt)
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     // function increments the semaphore and signals any threads that
00062     // are blocked waiting a change in the semaphore
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     // function decrements the semaphore and blocks if the semaphore is
00079     // <= 0 until another thread signals a change
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     // function does NOT block but simply decrements the semaphore
00099     // should not be used instead of down -- only for programs where
00100     // multiple threads must up on a semaphore before another thread
00101     // can go down, i.e., allows programmer to set the semaphore to
00102     // a negative value prior to using it for synchronization.
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     // function returns the value of the semaphore at the time the
00116     // critical section is accessed.  obviously the value is not guaranteed
00117     // after the function unlocks the critical section.
00118     //int operator()
00119     //{
00120     //      check_pthread_call(pthread_mutex_lock(&mutex));
00121     //      int res = v;
00122     //      check_pthread_call(pthread_mutex_unlock(&mutex));
00123     //      return res;
00124     //};
00125 };
00126 
00127 __STXXL_END_NAMESPACE
00128 
00129 #endif // !STXXL_SEMAPHORE_HEADER
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines