Boost logo

Boost :

From: brent verner (brent_at_[hidden])
Date: 2000-08-14 10:36:51


On 14 Aug 2000 at 08:39 (-0500), jsiek_at_[hidden] wrote:
| William Kempf writes:
| > I think it makes as much sense to nest the CV as it does the lock.
| > The CV can't exist with out the mutex, while the mutex can exist
| > withou the CV. Further, the CV is going to be as dependent
| > [ clip ]
| > > > while (!full)
| > > > lock.wait(cv);
| > >
| > > while (!full)
| > > cv.wait(lock);
| > >
| > > makes a little more sense to me.
| >
| > It makes more sense because it follows the logic of the pthreads
| > implementation. However, I think it makes sense to reverse them in
| > our own library because the lock is waiting on the condition.
|
| The fact that the Mutex concept can exist without the CV concept is an
| argument for my position, not yours ;) The Mutex concept should not
| make any mention of a CV. Having a CV typedef nested in Mutex, or
| having a wait() function in the Mutex's lock would make the Mutex
| concept dependent on the CV concept, which is the opposite of what we
| want. We want tight coupling, but it should go in the other direction.

   A condition variable must always be associated with a
   mutex, to avoid the race condition where a thread prepares
   to wait on a condition variable and another thread signals
   the condition just before the first thread actually waits
   on it.

Having the condition class derive from the mutex class will _enforce_
the required behavior from the (pthreads) condition variable.

something like below. note: i know, it's bad code, but I hope
you get the idea...

  Brent

=======================================================

class basic_lockable {
public:
  basic_lockable(){}
  virtual ~basic_lockable(){}
  virtual int lock() = 0;
  virtual int unlock() = 0;
};

template<typename __lock_t>
class basic_scoped_lock {
private:
  __lock_t* _M_lock;
public:
  basic_scoped_lock(__lock_t* arg) : _M_lock(arg){
    _M_lock->lock();
  }
  ~basic_scoped_lock(){
    _M_lock->unlock();
  }
};

typedef basic_scoped_lock<basic_lockable> scoped_lock;

class basic_mutex : public virtual basic_lockable {
private:
  pthread_mutex_t me_id;
public:
  basic_mutex() : basic_sharable() {
    pthread_mutex_init(&me_id, NULL);
  }
  virtual ~basic_mutex(){
    pthread_mutex_destroy(&me_id);
  }
  inline int lock(){
    return pthread_mutex_lock(&me_id);
  }
  inline int trylock(){ return pthread_mutex_trylock(&me_id); }
  inline int unlock(){
    return pthread_mutex_unlock(&me_id);
  }
};

class basic_condition : public basic_mutex
{
private:
  pthread_cond_t cond_id;
public:
  basic_condition() {
    pthread_cond_init(&cond_id, NULL);
  }
  virtual ~basic_condition(){
    pthread_cond_destroy(&cond_id);
  }
  inline int wait(){
    return pthread_cond_wait(&cond_id,&me_id);
  }
  inline int wait(long usec){
    timespec then;
    timeval now;
    gettimeofday(&now,NULL);
    int sec = usec / 1000000;
    usec = usec - sec * 1000000;
    then.tv_sec = now.tv_sec + sec;
    then.tv_nsec = (now.tv_usec + usec) * 1000;
    return pthread_cond_timedwait(&cond_id,&me_id,&then);
  }
  inline int broadcast(){
    return pthread_cond_broadcast(&cond_id);
  }
  inline int signal(){
    return pthread_cond_signal(&cond_id);
  }
};

class basic_semaphore : public virtual basic_lockable {
private:
  sem_t sem_id;
  int sem_count;
protected:
public:
  basic_semaphore(int counti = 0) {
    sem_init(&sem_id, 0, count);
  }
  virtual ~basic_semaphore(){
    sem_destroy(&sem_id);
  }
  inline int trywait(){
    return sem_trywait(&sem_id);
  }
  inline int post(){
    return sem_post(&sem_id);
  }
  inline int wait(){
    return sem_wait(&sem_id);
  }
  inline int value(){
    sem_getvalue(&sem_id, &sem_count);
    return sem_count;
  }
  inline int lock(){
    // how do semaphores lock ?
  }
  inline int unlock(){
    // and unlock ?
  }
};

-- 
Damon Brent Verner                        o      _     _         _
Cracker Jack® Surprise Certified  _o     /\_   _ \\o  (_)\__/o  (_)
brent_at_[hidden]                _< \_   _>(_) (_)/<_    \_| \   _|/' \/
brent_at_[hidden]               (_)>(_) (_)        (_)   (_)    (_)'  _\o_

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk