Boost logo

Boost :

From: kevin_vanhorn_at_[hidden]
Date: 2001-10-17 11:05:59


> I just noticed, to my dismay, that the thread library only
> implements weak semaphores.

I believe the following is a correct implementation of strong, fair
semaphores built on top of POSIX mutexes and condition variables.
It does depend on the assumption that POSIX mutexes are fair -- that
is, a thread blocked on a mutex cannot remain forever blocked as long
as every thread that locks the mutex eventually unlocks it.

class semaphore
{
  pthread_mutex_t mutex;
  pthread_cond_t signal_occurred;
  unsigned sem_cnt;
  std::queue<bool *, std::list<bool *> > blocked_list;
public:
  semaphore(unsigned cnt);
  
  void signal()
  {
    pthread_mutex_lock(&mutex);
    if (blocked_list.empty()) {
      ++sem_cnt;
    }
    else {
      *(blocked_list.front()) = false;
      blocked_list.pop();
      pthread_cond_broadcast(&signal_occurred);
    }
    pthread_mutex_unlock(&mutex);
  }

  void wait()
  {
    pthread_mutex_lock(&mutex);
    if (sem_cnt > 0) {
      --sem_cnt;
    }
    else {
      bool blocked = true;
      blocked_list.push(&blocked);
      while (blocked)
        pthread_cond_wait(&signal_occurred, &mutex);
    }
    pthread_mutex_unlock(&mutex);
  }

  ~semaphore()
  {
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&signal_occurred);
  }
};


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